今日头条文章采集软件(今日头条网站如何使用python爬虫抓取头条上面的新闻链接 )
优采云 发布时间: 2022-01-23 12:31今日头条文章采集软件(今日头条网站如何使用python爬虫抓取头条上面的新闻链接
)
今日头条爬虫实战文章前言
本篇博客主要记录如何使用python爬虫爬取今日头条上的新闻链接,然后跟随新闻链接爬取新闻的文字信息,以及新闻的热点信息,即评论数转发和喜欢。
一、如何获取请求url
先打开今日头条网站,注意选择左边的热点选项而不是推荐选项,即最后一个网址的后缀应该是news_hot
然后在当前页面按ctrl+shift+i进入浏览器开发者模式,右上角选择network,如下:
找到如下XHR文件,即中间有category=news_hot的XHR文件,前缀在URL中。![xhr]()
验证,点击预览可以看到所有新闻存储的数据都是以json格式存储的,如下:
查看每条新闻的内容:
这里的参数很多,包括媒体和图片的具体参数,新闻的标题和摘要,新闻来源的url等等,所以我们可以得到新闻的各种参数,方便爬取未来还有更多的事情。
二、爬虫测试
这时候,我们其实可以爬取了。今日头条的json文件不断更新。让我们尝试使用最简单的请求来爬取数据中的文件。
我们首先得到 User-agent 和 cookies
从刚刚打开的 XHR 文件的标题中:
如下所示
拿到后,用最简单的请求爬取:
考试时间为2020年12月10日
1import requests
2 #请求头的书写
3 headers = {
4 'User-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36',
5 'Cookie': 'csrftoken=a1cec75edb840d9c30e91b908b6df006; tt_webid=6903701895266567693; ttcid=de9284562a3d43158bbcf20f427c76bf38; s_v_web_id=verify_kifci8q5_95283jqK_hVnJ_46JY_BWm0_qh2CKMpqyzNp; tt_webid=6903701895266567693; passport_csrf_token=1360da074931584e4d0f4b71d11ecafe; sid_guard=888954813cb61b04ed109f48e8113b56%7C1607393426%7C5184000%7CSat%2C+06-Feb-2021+02%3A10%3A26+GMT; uid_tt=132acd819771d24afff611bdd48dc359; uid_tt_ss=132acd819771d24afff611bdd48dc359; sid_tt=888954813cb61b04ed109f48e8113b56; sessionid=888954813cb61b04ed109f48e8113b56; sessionid_ss=888954813cb61b04ed109f48e8113b56; tt_anti_token=LjrRoQn9d-fe7a8dbda23884fb006dfd76a297fa069a5ef454622aeb4f2994ae7dfe98ac87; __ac_signature=_02B4Z6wo00f017hqegwAAIBDAKwEUeNa15-4bn6AALHgKC7xunrfsuW0d0EgNAvNrli5JTxbZsoDbHSXIYivhqr4RNY5hZqu5s5PdidP7NkmcwuLCUaSrFmYbBzGkUxLlEUPzgL3ukXRVxfTc5; MONITOR_WEB_ID=5f72b98e-ffdf-406a-86be-15dee611591c; tt_scid=wHyPfUtWjE4zJRDRxq.8YEF2HX25EeVt8-bID9j3Txg3rI66rHH9D7xV9JXAMqKPdf64',
6 }
7 r = requests.get(url='https://www.toutiao.com/api/pc/feed/?min_behot_time=0&category=news_hot&utm_source=toutiao&widen=1&tadrequire=true&_signature=_02B4Z6wo00f01uYWKLAAAIBCXtBW7S9sSxbmEywAAOZltgS9dx7TKLd.DOq-TC1nLqQ1aA8.sbaw4YU0vtmmTo0wHJT7y1lZ4v3D4BmOdmNuyThwemlMFnGwhZIStsnlR46A4ymuGNCq1I9h32',headers=headers)
8 # 最基本的GET请求
9 print(r.status_code)
10 #输出请求状态码,200代表请求响应
11 print(r.text)
12 #这时输出的json文件是加密的
13 data = json.loads(r.text)
14 #使用json动态加载
15 print(data['data'])
16 #json文件访问
17 print(len(data['data']))
18 #新闻长度是12
19
20
输出就是我们刚才看到的数据文件中新闻的json文件:
这样我们就可以得到一个时间段头条的12条新闻的一些参数,我们可以建立一些列表来保存它们。
三、不停机爬虫
至于如何不断爬取更多的新闻,我们需要分析一下请求url是如何产生的。请参阅下表。表是去年的。当前的url组成可能发生了变化,但是只要我们能找到请求url的组成,也就是你可以不断爬取今日头条网站加载的json文件,挖掘出新闻信息,因为我没有搞了这么久,先写下去年的经验供大家参考,然后具体细节和今年的头条改了反爬虫机制,所以大家需要在这块下点功夫,然后就可以了得以实现。爬虫其实很简单。上面的简单请求是,你可以简单地先尝试一下,然后继续进行下一部分。
比较参数说明:
max_behot_time是从获取的json数据中获取的,具体数据如下截图所示:
到目前为止,我们只获得了爬虫的起始url。在后续的爬虫中,我们需要根据上面的参数表获取新闻的url,从而对新闻进行爬取。
继续上面的参数,python 得到 as 和 cp 值:
至于这两个值,去年爬的时候需要用到,可以在csdn找到相关博客了解如何获取as和cp值。至于硒和飞溅的方法,今年都失败了,今日头条升级了反爬措施。, 有针对性的封禁了大部分webdrivers,常用的已经不行了。现在前硬柱面sig参数好像不行。但是既然我们可以通过request方式访问json里面的数据,(上面简单的测试是在20201210)做的,所以应该可以直接获取url,相信你可以给!详情请参考博文破解标题url参数
去年我们只是随机发现了一个代码:
1def get_as_cp(): # 该函数主要是为了获取as和cp参数,程序参考今日头条中的加密js文件:home_4abea46.js
2 zz = {}
3 now = round(time.time())
4 print(now) # 获取当前计算机时间
5 e = hex(int(now)).upper()[2:] #hex()转换一个整数对象为16进制的字符串表示
6 print('e:', e)
7 a = hashlib.md5() #hashlib.md5().hexdigest()创建hash对象并返回16进制结果
8 print('a:', a)
9 a.update(str(int(now)).encode('utf-8'))
10 i = a.hexdigest().upper()
11 print('i:', i)
12 if len(e)!=8:
13 zz = {'as':'479BB4B7254C150',
14 'cp':'7E0AC8874BB0985'}
15 return zz
16 n = i[:5]
17 a = i[-5:]
18 r = ''
19 s = ''
20 for i in range(5):
21 s= s+n[i]+e[i]
22 for j in range(5):
23 r = r+e[j+3]+a[j]
24 zz ={
25 'as':'A1'+s+e[-3:],
26 'cp':e[0:3]+r+'E1'
27 }
28 print('zz:', zz)
29 return zz
30
31
这样就形成了一个完整的链接。还有一点要提的是,去掉_signature参数也可以得到json数据,这样请求的链接就完成了;完整的代码附在下面:
这段代码其实是有参考价值的。只要能找到今年头条url的相关参数,就可以继续进步。
其中,只要弄清楚今日头条的url构成,基本任务就成功了,加油!
1import requests
2import json
3from openpyxl import Workbook
4import time
5import hashlib
6import os
7import datetime
8 #可能不一样
9start_url = 'https://www.toutiao.com/api/pc/feed/?min_behot_time=0&category=news_hot&utm_source=toutiao&widen=1&max_behot_time='
10url = 'https://www.toutiao.com'
11
12headers={
13 'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'
14}
15cookies = {''} # 此处cookies可从浏览器中查找,为了避免被头条禁止爬虫
16
17max_behot_time = '0' # 链接参数
18title = [] # 存储新闻标题
19source_url = [] # 存储新闻的链接
20s_url = [] # 存储新闻的完整链接
21source = [] # 存储发布新闻的公众号
22media_url = {} # 存储公众号的完整链接
23
24
25def get_as_cp(): # 该函数主要是为了获取as和cp参数,程序参考今日头条中的加密js文件:home_4abea46.js
26 zz = {}
27 now = round(time.time())
28 print(now) # 获取当前计算机时间
29 e = hex(int(now)).upper()[2:] #hex()转换一个整数对象为16进制的字符串表示
30 print('e:', e)
31 a = hashlib.md5() #hashlib.md5().hexdigest()创建hash对象并返回16进制结果
32 print('a:', a)
33 a.update(str(int(now)).encode('utf-8'))
34 i = a.hexdigest().upper()
35 print('i:', i)
36 if len(e)!=8:
37 zz = {'as':'479BB4B7254C150',
38 'cp':'7E0AC8874BB0985'}
39 return zz
40 n = i[:5]
41 a = i[-5:]
42 r = ''
43 s = ''
44 for i in range(5):
45 s= s+n[i]+e[i]
46 for j in range(5):
47 r = r+e[j+3]+a[j]
48 zz ={
49 'as':'A1'+s+e[-3:],
50 'cp':e[0:3]+r+'E1'
51 }
52 print('zz:', zz)
53 return zz
54
55
56def getdata(url, headers, cookies): # 解析网页函数
57 r = requests.get(url, headers=headers, cookies=cookies)
58 print(url)
59 data = json.loads(r.text)
60 return data
61
62
63def savedata(title, s_url, source, media_url): # 存储数据到文件
64 # 存储数据到xlxs文件
65 wb = Workbook()
66 if not os.path.isdir(os.getcwd()+'/result'): # 判断文件夹是否存在
67 os.makedirs(os.getcwd()+'/result') # 新建存储文件夹
68 filename = os.getcwd()+'/result/result-'+datetime.datetime.now().strftime('%Y-%m-%d-%H-%m')+'.xlsx' # 新建存储结果的excel文件
69 ws = wb.active
70 ws.title = 'data' # 更改工作表的标题
71 ws['A1'] = '标题' # 对表格加入标题
72 ws['B1'] = '新闻链接'
73 ws['C1'] = '头条号'
74 ws['D1'] = '头条号链接'
75 for row in range(2, len(title)+2): # 将数据写入表格
76 _= ws.cell(column=1, row=row, value=title[row-2])
77 _= ws.cell(column=2, row=row, value=s_url[row-2])
78 _= ws.cell(column=3, row=row, value=source[row-2])
79 _= ws.cell(column=4, row=row, value=media_url[source[row-2]])
80
81 wb.save(filename=filename) # 保存文件
82
83
84
85def main(max_behot_time, title, source_url, s_url, source, media_url): # 主函数
86 for i in range(3): # 此处的数字类似于你刷新新闻的次数,正常情况下刷新一次会出现10条新闻,但夜存在少于10条的情况;所以最后的结果并不一定是10的倍数
87 ##--------------------------------------------
88 #这一部分就是url的组成部分肯定和今年不一样了,然后获取到的json文件的处理后面基本不难,就是分离出相应的参数
89 ascp = get_as_cp() # 获取as和cp参数的函数
90 demo = getdata(start_url+max_behot_time+'&max_behot_time_tmp='+max_behot_time+'&tadrequire=true&as='+ascp['as']+'&cp='+ascp['cp'], headers, cookies)
91 ##------------------------------------------
92 print(demo)
93 # time.sleep(1)
94 for j in range(len(demo['data'])):
95 # print(demo['data'][j]['title'])
96 if demo['data'][j]['title'] not in title:
97 title.append(demo['data'][j]['title']) # 获取新闻标题
98 source_url.append(demo['data'][j]['source_url']) # 获取新闻链接
99 source.append(demo['data'][j]['source']) # 获取发布新闻的公众号
100 if demo['data'][j]['source'] not in media_url:
101 media_url[demo['data'][j]['source']] = url+demo['data'][j]['media_url'] # 获取公众号链接
102 print(max_behot_time)
103 max_behot_time = str(demo['next']['max_behot_time']) # 获取下一个链接的max_behot_time参数的值
104 for index in range(len(title)):
105 print('标题:', title[index])
106 if 'https' not in source_url[index]:
107 s_url.append(url+source_url[index])
108 print('新闻链接:', url+source_url[index])
109 else:
110 print('新闻链接:', source_url[index])
111 s_url.append(source_url[index])
112 # print('源链接:', url+source_url[index])
113 print('头条号:', source[index])
114 print(len(title)) # 获取的新闻数量
115
116if __name__ == '__main__':
117 main(max_behot_time, title, source_url, s_url, source, media_url)
118 savedata(title, s_url, source, media_url)
119
120