6.获取环球时报关键词新闻--动态网页Ajax

一、背景

前段时间写了个爬虫获取新浪的新闻,但新浪新闻页面文档页格式不统一,新闻质量也较差,经过筛选,环球时报上面的新闻质量稍好,且页面格式比较统一。

二、实例解析

1.思路

  • 我们这里主要获取环球时报上面的国际新闻
  • 国际新闻URL:https://world.huanqiu.com/
  • 爬取新闻的三步法:解析主页上面的新闻链接---->解析每个新闻链接里面的内容---->格式化文本写入文档

2.新闻链接解析

  • 常规套路,打开主页,检查元素,找到一个新闻的元素位置

6.获取环球时报关键词新闻--动态网页Ajax

  • 容易发现上图中,“多米尼克”新闻的元素位置如下:

  • selector为"#recomend li a",但写入代码后,可以发现是找不到这个元素的,可以猜测是动态加载的网页
  • 同样的可以验证,打开主页源代码,我们搜索这条新闻是搜索不到的。

6.获取环球时报关键词新闻--动态网页Ajax

  • 点击检查元素的‘网络’选项卡,容易发现该网页动态加载的,在‘预览’中可以发现包含了当前页面的20条新闻数据,Json格式保存;

6.获取环球时报关键词新闻--动态网页Ajax

  • 接下来就是拼凑新闻链接

6.获取环球时报关键词新闻--动态网页Ajax

  • 这里主要关注下url中的offset为偏移量,通俗的讲就是页码,offset=0即为第1页,offset=20即为第2页,依次类推

接着解析每条新闻的地址,jsons数据中,aid即为该新闻的保存名,如aid为42BY7TXsqIc,那么该新闻的链接就是:https://world.huanqiu.com/article/42BY7TXsqIc;title为标题名,我们从json中获取这两条就够了

  • 下面是新闻链接解析模块的代码
#获取新闻链接
keyword='新冠'
count=int(input('请输入爬取页码数(1,2,3.....):'))
news_title=[]
news_url=[]
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.182 Safari/537.36 Edg/88.0.705.81",
    "Cookie":'''UM_distinctid=177f21c29bf10d-043ddbd82b4eef-7a667166-144000-177f21c29c039b; _ma_tk=hewd6oh2rs0o2mqybcrd3s60un56m46w; REPORT_UID_=cJ869QdbSP132oZ6591juDJYZZ8wK0SC; Hm_lvt_1fc983b4c305d209e7e05d96e713939f=1614674668,1614738118,1614738291,1614908983; CNZZDATA1000010102=1231572127-1614671036-https%253A%252F%252Fwww.huanqiu.com%252F%7C1614914069; Hm_lpvt_1fc983b4c305d209e7e05d96e713939f=1614914406'''
}
path = 'https://world.huanqiu.com/api/list?node=%22/e3pmh22ph/e3pmh2398%22,%22/e3pmh22ph/e3pmh26vv%22,%22/e3pmh22ph/e3pn6efsl%22,%22/e3pmh22ph/efp8fqe21%22&offset={0}&limit=20'
print('开始爬取新闻链接...')
for i in tqdm(range(0,count)):
    try:
        url=path.format(20*i)    #offset为20
        res = requests.get(url,headers=headers)
        if res.content:
            items=res.json().get('list')
            for item in items:
                title=item.get('title')    
                aid=item.get('aid')
                if keyword in str(title) and title not in news_title:   #筛选关键词
                    url='https://world.huanqiu.com/article/'+str(aid)
                    news_title.append(item.get('title'))
                    news_url.append(url)            
        else:
            print('无内容')
    except res.ConnectionError:
        print('error')

3.新闻内容解析

  • 内容解析就很简单了,选定元素位置循环起来就ok了

6.获取环球时报关键词新闻--动态网页Ajax

#获取新闻内容
news_content=[]
news_time=[]
news_source=[]
print('开始爬取新闻内容....')
for url in tqdm(news_url):    
    req=requests.get(url)
    req.encoding='utf-8'
    soup=BeautifulSoup(req.text,'lxml')
    #获取新闻发布时间和来源
    reg_source=soup.select('div.metadata-info')    
    str_source=re.findall('<a href=".*">(.*)</a>',str(reg_source),re.S)
    news_source.append(str_source)
    str_time=re.findall('<p class="time">(.*)</p>',str(reg_source),re.S) 
    news_time.append(str_time)        
    #获取新闻内容
    reg_content=soup.select('.l-con.clear')
    str_data=re.findall('<p>(.*?)</p>',str(reg_content),re.S)  #re.S参数,多行匹配
    str_data=''.join(str_data)  #将data中的数组拼成一个字符串
    #剔除<i>标签中的内容
    pat_str1='<i class="pic-con">.*</i>'
    pat_str2='<em data-scene="strong">.*</em>'  #剔除:<em data-scene="strong">海外网3月5日电</em>
    str_data=re.sub(pat_str1,'',str_data)
    str_data=re.sub(pat_str2,'',str_data)    
    news_content.append(str_data)

4.保存文本

#写入txt文本
print('开始写入文本....') 
write_flag = True
txtname='0305.txt'
with open(txtname, 'w', encoding='utf-8') as f:
    for i in range(len(news_title)):                
        if news_content[i]!='':
            f.writelines(news_title[i])
            f.writelines('\n')
            f.writelines(news_source[i])
            f.writelines('\n')
            f.writelines(news_time[i])
            f.writelines('\n')
            f.writelines(news_content[i])            
        else:
            continue
        f.write('\n\n\n')
    f.close()

三、小结

  • 动态网页的爬取,关键在于解析新闻链接,通过抓包分析出请求链接和json数据包,从中找到关键信息即可

四、代码

import requests
import re
import json
from urllib.parse import urlencode
from bs4 import BeautifulSoup
from tqdm import tqdm


# 下载新闻链接
keyword='新冠'
count=int(input('请输入爬取页码数(1,2,3.....):'))
news_title=[]
news_url=[]
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.182 Safari/537.36 Edg/88.0.705.81",
    "Cookie":'''UM_distinctid=177f21c29bf10d-043ddbd82b4eef-7a667166-144000-177f21c29c039b; _ma_tk=hewd6oh2rs0o2mqybcrd3s60un56m46w; REPORT_UID_=cJ869QdbSP132oZ6591juDJYZZ8wK0SC; Hm_lvt_1fc983b4c305d209e7e05d96e713939f=1614674668,1614738118,1614738291,1614908983; CNZZDATA1000010102=1231572127-1614671036-https%253A%252F%252Fwww.huanqiu.com%252F%7C1614914069; Hm_lpvt_1fc983b4c305d209e7e05d96e713939f=1614914406'''
}
path = 'https://world.huanqiu.com/api/list?node=%22/e3pmh22ph/e3pmh2398%22,%22/e3pmh22ph/e3pmh26vv%22,%22/e3pmh22ph/e3pn6efsl%22,%22/e3pmh22ph/efp8fqe21%22&offset={0}&limit=20'

print('开始爬取新闻链接...')
for i in tqdm(range(0,count)):
    try:
        url=path.format(20*i)    #offset为20
        res = requests.get(url,headers=headers)
        if res.content:
            items=res.json().get('list')
            for item in items:
                title=item.get('title')    
                aid=item.get('aid')
                if keyword in str(title) and title not in news_title:   #筛选关键词
                    url='https://world.huanqiu.com/article/'+str(aid)
                    news_title.append(item.get('title'))
                    news_url.append(url)            
        else:
            print('无内容')
    except res.ConnectionError:
        print('error')

#获取新闻内容
news_content=[]
news_time=[]
news_source=[]
print('开始爬取新闻内容....')
for url in tqdm(news_url):    
    req=requests.get(url)
    req.encoding='utf-8'
    soup=BeautifulSoup(req.text,'lxml')

    #获取新闻发布时间和来源
    reg_source=soup.select('div.metadata-info')    
    str_source=re.findall('<a href=".*">(.*)</a>',str(reg_source),re.S)
    news_source.append(str_source)
    str_time=re.findall('<p class="time">(.*)</p>',str(reg_source),re.S) 
    news_time.append(str_time)         
 
    #获取新闻内容
    reg_content=soup.select('.l-con.clear')
    str_data=re.findall('<p>(.*?)</p>',str(reg_content),re.S)  #re.S参数,多行匹配
    str_data=''.join(str_data)  #将data中的数组拼成一个字符串
    #剔除<i>标签中的内容
    pat_str1='<i class="pic-con">.*</i>'
    pat_str2='<em data-scene="strong">.*</em>'  #剔除:<em data-scene="strong">海外网3月5日电</em>
    str_data=re.sub(pat_str1,'',str_data)
    str_data=re.sub(pat_str2,'',str_data)    
    news_content.append(str_data)


#写入txt文本
print('开始写入文本....')    
write_flag = True
txtname='0305.txt'
with open(txtname, 'w', encoding='utf-8') as f:
    for i in tqdm(range(len(news_title))):                
        if news_content[i]!='':
            f.writelines(news_title[i])
            f.writelines('\n')
            f.writelines(news_source[i])
            f.writelines('\n')
            f.writelines(news_time[i])
            f.writelines('\n')
            f.writelines(news_content[i])            
        else:
            continue
        f.write('\n\n\n\n')
    f.close()

print('---结束---')
上一篇:【电商12】newsflash news


下一篇:爬虫快速入门(二):动态页面抓取