百度新闻爬虫搜索引擎实战---爬虫篇(1)

爬虫部分

首先,我们得爬取百度新闻的信息。
爬虫分为两部分:

  1. 获取新闻链接
  2. 通过链接爬取新闻信息

新闻链接爬取(1)

1.获取新闻链接

1.1 分析请求

打开chrome浏览器,输入百度新闻链接,按F12打开开发者工具,依次点击Network->Doc,再刷新一次网页,效果如下:
百度新闻爬虫搜索引擎实战---爬虫篇(1)_第1张图片

我们看到了所有返回doc的请求。接着,我们点击Preview选项卡:
百度新闻爬虫搜索引擎实战---爬虫篇(1)_第2张图片
通过预览,我们可以看到这个请求热点要闻、热搜新闻词和百家号三个模块的信息,这些蓝色的链接就是我们要的新闻链接。

点击Headers选项,我们可以看到请求的构造:
百度新闻爬虫搜索引擎实战---爬虫篇(1)_第3张图片
很好,我们现在就可以通过构造类似请求来获取到热点要闻、热搜新闻词和百家号三个模块的信息了。

构造请求,获取相应,解析html。

但是,事情并不简单。我们滚动页面:
百度新闻爬虫搜索引擎实战---爬虫篇(1)_第4张图片
百度新闻爬虫搜索引擎实战---爬虫篇(1)_第5张图片
百度新闻爬虫搜索引擎实战---爬虫篇(1)_第6张图片
我们发现还有一些模块并不在我们找到的那个请求中。

我们判断,这些内容是在我们滚动页面时通过动态加载上去的。

点击XHR选项卡,我们找到了一些线索:
百度新闻爬虫搜索引擎实战---爬虫篇(1)_第7张图片
我们发现这些请求都带着一个 id 属性,而这些属性的中文恰巧对应我们看到的那个模块的名字。

我们看看第一个xhr类型请求:
百度新闻爬虫搜索引擎实战---爬虫篇(1)_第8张图片
它比我们找到的第一个请求多了一个Query String Parameters 属性,id表示模块名,t表示时间,ajax表示返回类型。

百度新闻爬虫搜索引擎实战---爬虫篇(1)_第9张图片

这个时间如果用 ms 表示49年多,而计算器时间都是从1970年开始算起,所以这个数字表示的是ms。

看完了请求的结构,我们可以看看服务器相应的内容了
百度新闻爬虫搜索引擎实战---爬虫篇(1)_第10张图片
这个请求返回了一个json 结构数据,新闻链接就放在键值对内。
百度新闻爬虫搜索引擎实战---爬虫篇(1)_第11张图片
除了当地新闻模块,其他模块的请求都返回了一个html,新闻链接放在html中。值得注意的是这些模块的请求的Query String Parameters 属性中没有ajax键。

1.2 构造请求

我们暂时放下第一个请求。

我们首先实现返回json数据的请求:

import requests
import json
url = 'http://news.baidu.com/widget?id=LocalNews&ajax=json&t=1565742671236'
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3',
    'Referer': 'http://news.baidu.com/guoji',
    'Accept-Encoding': 'gzip, deflate',
    'Accept-Language': 'zh-CN,zh;q=0.9',
    'Cookie': 'BAIDUID=BB2DCB09D0BCEF14D99F6A6A6CE5A1DB:FG=1; BIDUPSID=BB2DCB09D0BCEF14D99F6A6A6CE5A1DB; PSTM=1549988189; BDUSS=H40YlBUdE5FaklweFFvc2szYmpILWRTdGlGeTlPRUxYZ3hPdVctQXVDYWVmelZkSVFBQUFBJCQAAAAAAAAAAAEAAAAVmE-ksKLA78K3ybXJtQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJ7yDV2e8g1dd; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; H_PS_PSSID=1450_21092_29522_29518_29098_29568_28831_29221_22159; BDSFRCVID=M_0sJeCCxG3jeU3w_mtxLaFULTy8O-bEthyW3J; H_BDCLCKID_SF=tbkD_C-MfIvjHn8z2KT8bKCShUFsK6jW-2Q-5hOy3KO8eqRv5pnGX4P-KHrf3x6dtNLqL-L2MPOvhpFuDTtajj3QeaRt2tcyatj2WnTJ25r8e5rnhPF3yftTKP6-3MJO3b7B0l7FbM7G8h6bMf8By58dyajCQlkHaI5mohFLtDKhbKKCj5RMK4_SMUoHetrK-D5XQbC8Kb7VbpTEDMnkbfJBDGJR5-Pq-jvdblRhBCQIjMnTyURdXlD7yajKBlvWWmbx2Ron3RQTjnOqKPTpQT8r5b_OK5Oib4j-KbONab3vOpRzXpO1KMPzBN5thURB2DkO-4bCWJ5TMl5jDh05y6TXDN0qtTteJb3fL-08MJnEqbTkq4bohjPyX-jeBtQm05bxobLyJD5b_n6Ljn8MMpkS-P5n0jcqbHrDs4PbWDFKMC_GjjthDjPVMmTt2tc2K6r-04_8Kb7VbIJCXMnkbftWXfvmQ-oI-jvdWx5n2t5ZSfnueMri5bK7yajK2hTJbD3MVlrh3bvsVCbPQJ7pQT8ryhAOK5OibCrk2b5oab3vOpRzXpO1KMPzBN5thURB2DkO-4bCWJ5TMl5jDh05y6TLeHLDtTkqtR3tWJTOaj6jDbTnMIT8bKCShUFsy5cJB2Q-5KL--qoZeJ4G5pnVMMtq5JrPXPnpJCczafbdJJjoh4Pl-to2-fD7jnQHKTQdBgTxoUJh5DnJhhvG-xAb54LebPRiWPr9QgbjahQ7tt5W8ncFbT7l5hKpbt-q0x-jLn7ZVDD5fCtMMItr5b5H-PQHjHQB2-DXKKOLVh67tPOkeqOJ2Mt5M4LADpJd2R3OBI6l-lRmMCncKJoH5-7B3TtpexbH55uqJR4JVU5; Hm_lvt_e9e114d958ea263de46e080563e254c4=1565684960; LOCALGX=%u957F%u6C99%7C%35%31%36%32%7C%u957F%u6C99%7C%35%31%36%32; delPer=0; BDRCVFR[feWj1Vr5u3D]=I67x6TjHwwYf0; PSINO=3; Hm_lpvt_e9e114d958ea263de46e080563e254c4=1565742579',
}
response = requests.get(url=url,headers=headers)
data = []
if response.status_code == 200:
    data=json.loads(response.text)

输出:

{'errno': 0,
 'request_id': '0701106945',
 'timestamp': 1565748701,
 'data': {'LocalNews': {'errno': 0,
   'data': {'cityid': 5162,
    'name': '长沙',
    'rows': {'pic': {'url': 'http://baijiahao.baidu.com/s?id=1641760525400781448',
      'title': '两车相撞人员被困,长沙消防成功救援',
      'time': '22:00',
      'imgUrl': 'https://t11.baidu.com/it/u=1842898135,1137066914&fm=173&app=49&f=JPEG?w=218&h=146&s=5F3290E711C49F435875BCB703007001'},
     'first': [{'url': 'http://baijiahao.baidu.com/s?id=1641804248809095870',
       'title': '「夏日长镜头」李小青:一天过手逾2000根滚烫...',
       'time': '09:35',
       'imgUrl': 'http://t10.baidu.com/it/u=3569769465,3052942297&fm=173&app=49&f=JPEG?w=218&h=146&s=EBB00FC740703D8A7CB04F680300A01B'},
      {'url': 'http://baijiahao.baidu.com/s?id=1641803120457332923',
       'title': '百日大会战全纪录|抢抓利好天气 美宜佳(湖南)...',
       'time': '09:17',
       'imgUrl': 'http://t12.baidu.com/it/u=7268816,847537983&fm=173&app=49&f=JPEG?w=218&h=146&s=9E8A6CC96A2F21071985AC130300C0D2'},
    	 ......
      {'url': 'http://baijiahao.baidu.com/s?id=1641723919118977084',
       'title': '湖南清晨突降暴雨!终于凉快了!接下来……',
       'time': '12:18',
       'imgUrl': 'http://t12.baidu.com/it/u=3300258029,584678755&fm=173&app=49&f=JPEG?w=218&h=146&s=2BE6722246848CA289BCF4CA0100A0E1'},
      {'url': 'http://baijiahao.baidu.com/s?id=1641750202887330237',
       'title': '长沙消防7月处置937个马蜂窝',
       'time': '19:16',
       'imgUrl': 'http://t10.baidu.com/it/u=754302183,953699378&fm=173&app=49&f=JPEG?w=218&h=146&s=72B11AC120A2411501B5B15A03008090'},
     
      {'url': 'http://baijiahao.baidu.com/s?id=1641722142319250930',
       'title': '命运多舛的长沙市042号“双限地”成功“再嫁”...',
       'time': '11:50',
       'imgUrl': 'http://t12.baidu.com/it/u=107624057,1688297014&fm=173&app=49&f=JPEG?w=218&h=146&s=A454EC36531A6C695AC505CB0300E032'},
      {'url': 'http://baijiahao.baidu.com/s?id=1641755644328509610',
       'title': '提醒丨体重骤降是减肥成功?原来是患了这种病',
       'time': '20:43',
       'imgUrl': 'http://t11.baidu.com/it/u=4243350295,2093996368&fm=173&app=49&f=JPEG?w=218&h=146&s=41362D72BBC050C24CC971ED0300A030'}]}},
   'ad': None}}}

显然,我们成功了。

json信息是最好处理的,所以我们能不能让其他模块的信息的也用json传过来呢?我们想到了ajax键…

试试便知:

import requests
import json
url = 'http://news.baidu.com/widget?id=civilnews&ajax=json&t=1565742671236'
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3',
    'Referer': 'http://news.baidu.com/guoji',
    'Accept-Encoding': 'gzip, deflate',
    'Accept-Language': 'zh-CN,zh;q=0.9',
    'Cookie': 'BAIDUID=BB2DCB09D0BCEF14D99F6A6A6CE5A1DB:FG=1; BIDUPSID=BB2DCB09D0BCEF14D99F6A6A6CE5A1DB; PSTM=1549988189; BDUSS=H40YlBUdE5FaklweFFvc2szYmpILWRTdGlGeTlPRUxYZ3hPdVctQXVDYWVmelZkSVFBQUFBJCQAAAAAAAAAAAEAAAAVmE-ksKLA78K3ybXJtQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJ7yDV2e8g1dd; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; H_PS_PSSID=1450_21092_29522_29518_29098_29568_28831_29221_22159; BDSFRCVID=M_0sJeCCxG3jeU3w_mtxLaFULTy8O-bEthyW3J; H_BDCLCKID_SF=tbkD_C-MfIvjHn8z2KT8bKCShUFsK6jW-2Q-5hOy3KO8eqRv5pnGX4P-KHrf3x6dtNLqL-L2MPOvhpFuDTtajj3QeaRt2tcyatj2WnTJ25r8e5rnhPF3yftTKP6-3MJO3b7B0l7FbM7G8h6bMf8By58dyajCQlkHaI5mohFLtDKhbKKCj5RMK4_SMUoHetrK-D5XQbC8Kb7VbpTEDMnkbfJBDGJR5-Pq-jvdblRhBCQIjMnTyURdXlD7yajKBlvWWmbx2Ron3RQTjnOqKPTpQT8r5b_OK5Oib4j-KbONab3vOpRzXpO1KMPzBN5thURB2DkO-4bCWJ5TMl5jDh05y6TXDN0qtTteJb3fL-08MJnEqbTkq4bohjPyX-jeBtQm05bxobLyJD5b_n6Ljn8MMpkS-P5n0jcqbHrDs4PbWDFKMC_GjjthDjPVMmTt2tc2K6r-04_8Kb7VbIJCXMnkbftWXfvmQ-oI-jvdWx5n2t5ZSfnueMri5bK7yajK2hTJbD3MVlrh3bvsVCbPQJ7pQT8ryhAOK5OibCrk2b5oab3vOpRzXpO1KMPzBN5thURB2DkO-4bCWJ5TMl5jDh05y6TLeHLDtTkqtR3tWJTOaj6jDbTnMIT8bKCShUFsy5cJB2Q-5KL--qoZeJ4G5pnVMMtq5JrPXPnpJCczafbdJJjoh4Pl-to2-fD7jnQHKTQdBgTxoUJh5DnJhhvG-xAb54LebPRiWPr9QgbjahQ7tt5W8ncFbT7l5hKpbt-q0x-jLn7ZVDD5fCtMMItr5b5H-PQHjHQB2-DXKKOLVh67tPOkeqOJ2Mt5M4LADpJd2R3OBI6l-lRmMCncKJoH5-7B3TtpexbH55uqJR4JVU5; Hm_lvt_e9e114d958ea263de46e080563e254c4=1565684960; LOCALGX=%u957F%u6C99%7C%35%31%36%32%7C%u957F%u6C99%7C%35%31%36%32; delPer=0; BDRCVFR[feWj1Vr5u3D]=I67x6TjHwwYf0; PSINO=3; Hm_lpvt_e9e114d958ea263de46e080563e254c4=1565742579',
}
response = requests.get(url=url,headers=headers)
data = []
if response.status_code == 200:
    data=json.loads(response.text)

我们直接修改将id改成civilnews。将data输出:

{'errno': 0,
 'request_id': '1459275082',
 'timestamp': 1565749459,
 'data': {'civilnews': {'title': '国内',
   'name': 'civilnews',
   'subClass': [......]
   'focusNews': [{'ID': '11563334',
     'TS': '2019-08-13 10:30:08',
     'm_class_id': '-1',
     'm_local_id': '-1',
     'm_url': 'http://xhpfmapi.zhongguowangshi.com/vh512/share/6386641?channel=weixin&from=singlemessage&isappinstalled=0',
     'm_title': '人生榜样——追记“良医”冯传汉',
     'm_site': '',
     'm_editor': '',
     'm_news_time': '0',
     'm_public_time': '10:30',
     'm_text': '',
     'm_image_url': '',
     'm_is_picnews': '0',
     'm_is_vidnews': '0',
     'm_is_manualnews': '1',
     'm_ext_type': '9',
     'm_ext': '',
     'm_topic_id': 0,
     'm_relate_count': '0',
     'm_same_count': '0',
     'm_relate_url': '',
     'm_v_table': 't_class_focus',
     'm_v_class_id': '1',
     'm_v_local_id': '-20480000',
     'm_v_topic_id': '-20480000',
     'm_v_tag': 'class_focustop',
     'm_position': '1',
     'm_user': 'luoxiao11',
     'm_add_time': '1565663408',
     'm_time_start': '0',
     'm_time_end': '1565756992',
     '_ext': [],
     '_url_type': 1,
     'm_public_time_seconds': '1565663408'},
    ......
    {'ID': '11480129',
     'TS': '2019-07-31 14:42:39',
     'm_class_id': '-1',
     'm_local_id': '-1',
     'm_url': 'http://news.cctv.com/2019/07/31/ARTIZtwYhlYknpH7KeXK6fBv190731.shtml?spm=C94212.PxBacxQyDqwK.S95581.201',
     'm_title': '工伤赔偿遇争议,这几点你要了解',
     'm_site': '',
     'm_editor': '',
     'm_news_time': '0',
     'm_public_time': '14:42',
     'm_text': '',
     'm_image_url': '',
     'm_is_picnews': '0',
     'm_is_vidnews': '0',
     'm_is_manualnews': '1',
     'm_ext_type': '9',
     'm_ext': '',
     'm_topic_id': 0,
     'm_relate_count': '0',
     'm_same_count': '0',
     'm_relate_url': '',
     'm_v_table': 't_class_tophit',
     'm_v_class_id': '1',
     'm_v_local_id': '-20480000',
     'm_v_topic_id': '-20480000',
     'm_v_tag': 'class_focustop',
     'm_position': '5',
     'm_user': 'yangliuqianjing',
     'm_add_time': '1564555359',
     'm_time_start': '0',
     'm_time_end': '1567233744',
     '_ext': [],
     '_url_type': 1,
     'm_public_time_seconds': '1564555359'}]}}}

信息比html要多。所以,我们可以通过修改id直接获取模块的json类型的数据。我们将id收集起来,作为一个数组:

widget_ids = ['LocalNews',
              'civilnews',
              'InternationalNews',
              'EnterNews',
              'SportNews',
              'FinanceNews',
              'TechNews',
              'MilitaryNews',
              'InternetNews',
              'DiscoveryNews',
              'LadyNews',
              'HealthNews',
              'PicWall']

然后遍历数组,便可以构造不同的请求来获取到相应模块的新闻链接了。

1.3 解析请求

json数据解析很简单,直接get().get()就完事了。上代码:

widget_id = widget_ids[5]
......
news_list = data.get('data').get(widget_id).get('focusNews')
news_urls = []
for news in news_list:
    news_urls.append(news['m_url'])

输出news_urls看看:

['http://baijiahao.baidu.com/s?id=1641789631757983484',
 'http://baijiahao.baidu.com/s?id=1641732315026022896',
 'http://baijiahao.baidu.com/s?id=1641716074849433290',
 'http://baijiahao.baidu.com/s?id=1641717506132624235',
 'http://baijiahao.baidu.com/s?id=1641716122873360445',
 'http://baijiahao.baidu.com/s?id=1641731396468766645',
 'http://baijiahao.baidu.com/s?id=1641716236638480148',
 'http://baijiahao.baidu.com/s?id=1641719146849962071',
 'http://baijiahao.baidu.com/s?id=1641716249431083379',
 'http://baijiahao.baidu.com/s?id=1641721487025992126',
 'http://baijiahao.baidu.com/s?id=1641716466864994412',
 'http://baijiahao.baidu.com/s?id=1641734821937582002',
 'http://baijiahao.baidu.com/s?id=1641716501086635804',
 'http://baijiahao.baidu.com/s?id=1641717769458226714',
 'http://baijiahao.baidu.com/s?id=1641716504997823224',
 'http://baijiahao.baidu.com/s?id=1641732826977878578',
 'http://baijiahao.baidu.com/s?id=1641716205623466920',
 'http://baijiahao.baidu.com/s?id=1641728094582501670',
 'http://baijiahao.baidu.com/s?id=1641716590072086360',
 'http://baijiahao.baidu.com/s?id=1641717347541413195',
 'http://baijiahao.baidu.com/s?id=1641716086646879984']

完美!

你可能感兴趣的:(百度新闻爬虫搜索引擎实战---爬虫篇(1))