首先,我们得爬取百度新闻的信息。
爬虫分为两部分:
打开chrome浏览器,输入百度新闻链接,按F12打开开发者工具,依次点击Network->Doc,再刷新一次网页,效果如下:
我们看到了所有返回doc的请求。接着,我们点击Preview选项卡:
通过预览,我们可以看到这个请求热点要闻、热搜新闻词和百家号三个模块的信息,这些蓝色的链接就是我们要的新闻链接。
点击Headers选项,我们可以看到请求的构造:
很好,我们现在就可以通过构造类似请求来获取到热点要闻、热搜新闻词和百家号三个模块的信息了。
构造请求,获取相应,解析html。
但是,事情并不简单。我们滚动页面:
我们发现还有一些模块并不在我们找到的那个请求中。
我们判断,这些内容是在我们滚动页面时通过动态加载上去的。
点击XHR选项卡,我们找到了一些线索:
我们发现这些请求都带着一个 id 属性,而这些属性的中文恰巧对应我们看到的那个模块的名字。
我们看看第一个xhr类型请求:
它比我们找到的第一个请求多了一个Query String Parameters 属性,id表示模块名,t表示时间,ajax表示返回类型。
这个时间如果用 ms 表示49年多,而计算器时间都是从1970年开始算起,所以这个数字表示的是ms。
看完了请求的结构,我们可以看看服务器相应的内容了
这个请求返回了一个json 结构数据,新闻链接就放在键值对内。
除了当地新闻模块,其他模块的请求都返回了一个html,新闻链接放在html中。值得注意的是这些模块的请求的Query String Parameters 属性中没有ajax键。
我们暂时放下第一个请求。
我们首先实现返回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']
然后遍历数组,便可以构造不同的请求来获取到相应模块的新闻链接了。
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']
完美!