Python爬虫——新闻热点爬取 中国新闻网,今日头条,

淡淡的烟草味﹌ 2021-07-25 18:25 1272阅读 0赞

在这里插入图片描述


QQ 1274510382
Wechat JNZ_aming
商业联盟 QQ群538250800
技术搞事 QQ群599020441
解决方案 QQ群152889761
加入我们 QQ群649347320
共享学习 QQ群674240731
纪年科技aming
网络安全 ,深度学习,嵌入式,机器强化,生物智能,生命科学。

叮叮叮:产品已上线 —>关注 官方-微信公众号——济南纪年信息科技有限公司
民生项目:商城加盟/娱乐交友/创业商圈/外包兼职开发-项目发布/
安全项目:态势感知防御系统/内网巡查系统
云服项目:动态扩容云主机/域名/弹性存储-数据库-云盘/API-AIeverthing
产品咨询/服务售后(同)

纸上得来终觉浅,绝知此事要躬行 !!! 寻找志同道合伙伴创业中。。。抱团滴滴aming联系方式!!


#本文为广告系统自动投放广告

# 如有侵权 删改 请速速联系我们





显示更多

可以看到相关的数据接口,里面有新闻标题以及新闻详情的url地址

如何提取url地址

  1. 1、转成json,键值对取值;
  2. 2、用正则表达式匹配url地址;

根据接口数据链接中的pager 变化进行翻页,其对应的就是页码。

详情页可以看到新闻内容都是在 div标签里面 p 标签内,按照正常的解析网站即可获取新闻内容。

  1. 保存方式

txt文本形式
PDF形式

  1. 整体爬取思路总结
  2. 在栏目列表页中,点击更多新闻内容,获取接口数据url
  3. 接口数据url中返回的数据内容中匹配新闻详情页url
  4. 使用常规解析网站操作(recssxpath)提取新闻内容
  5. 保存数据
  6. import parsel
  7. import requests
  8. import re
  9. #### 获取网页源代码
  10. def get_html(html_url):
  11. """
  12. 获取网页源代码 response
  13. :param html_url: 网页url地址
  14. :return: 网页源代码
  15. """
  16. headers = {
  17. "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.135 Safari/537.36",
  18. "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9", }
  19. response = requests.get(url=html_url, headers=headers)
  20. return response
  21. #### 获取每篇新闻url地址
  22. def get_page_url(html_data):
  23. """
  24. 获取每篇新闻url地址
  25. :param html_data: response.text
  26. :return: 每篇新闻的url地址
  27. """
  28. page_url_list = re.findall('"url":"(.*?)"', html_data)
  29. return page_url_list
  30. #### 文件保存命名不能含有特殊字符,需要对新闻标题进行处理
  31. def file_name(name):
  32. """
  33. 文件命名不能携带 特殊字符
  34. :param name: 新闻标题
  35. :return: 无特殊字符的标题
  36. """
  37. replace = re.compile(r'[\\\/\:\*\?\"\<\>\|]')
  38. new_name = re.sub(replace, '_', name)
  39. return new_name
  40. ####保存数据
  41. def download(content, title):
  42. """
  43. with open 保存新闻内容 txt
  44. :param content: 新闻内容
  45. :param title: 新闻标题
  46. :return:
  47. """
  48. path = '新闻\\' + title + '.txt'
  49. with open(path, mode='a', encoding='utf-8') as f:
  50. f.write(content)
  51. print('正在保存', title)
  52. ### 主函数
  53. def main(url):
  54. """
  55. 主函数
  56. :param url: 新闻列表页 url地址
  57. :return:
  58. """
  59. html_data = get_html(url).text # 获得接口数据response.text
  60. lis = get_page_url(html_data) # 获得新闻url地址列表
  61. for li in lis:
  62. page_data = get_html(li).content.decode('utf-8', 'ignore') # 新闻详情页 response.text
  63. selector = parsel.Selector(page_data)
  64. title = re.findall('<title>(.*?)</title>', page_data, re.S)[0] # 获取新闻标题
  65. new_title = file_name(title)
  66. new_data = selector.css('#cont_1_1_2 div.left_zw p::text').getall()
  67. content = ''.join(new_data)
  68. download(content, new_title)
  69. if __name__ == '__main__':
  70. for page in range(1, 101):
  71. url_1 = 'https://channel.chinanews.com/cns/cjs/gj.shtml?pager={}&pagenum=9&t=5_58'.format(page)
  72. main(url_1)

在浏览器开发者模式network下很快能找到一个‘?category=new_hot…’字样的文件,查看该文件发现新闻内容的数据全部存储在data里面,且能发现数据类型为json;

只要找到这个文件的requests url即可通过python requests来爬取网页了;

查看请求的url,
发现链接为:https://www.toutiao.com/api/pc/feed/?category=news\_hot&utm\_source=toutiao&widen=1&max\_behot\_time=0&max\_behot\_time\_tmp=0&tadrequire=true&as=A1B5AC16548E0FA&cp=5C647E601F9AEE1&\_signature=F09fYAAASzBjiSc9oUU9MxdPX3
在这里插入图片描述其中max_behot_time在获取的json数据中获得 :

在网上找了下大神对as和cp算法的分析,
发现两个参数在js文件:home_4abea46.js中有,具体算法如下代码:

  1. !function(t) {
  2. var e = { };
  3. e.getHoney = function() {
  4. var t = Math.floor((new Date).getTime() / 1e3)
  5. , e = t.toString(16).toUpperCase()
  6. , i = md5(t).toString().toUpperCase();
  7. if (8 != e.length)
  8. return {
  9. as: "479BB4B7254C150",
  10. cp: "7E0AC8874BB0985"
  11. };
  12. for (var n = i.slice(0, 5), a = i.slice(-5), s = "", o = 0; 5 > o; o++)
  13. s += n[o] + e[o];
  14. for (var r = "", c = 0; 5 > c; c++)
  15. r += e[c + 3] + a[c];
  16. return {
  17. as: "A1" + s + e.slice(-3),
  18. cp: e.slice(0, 3) + r + "E1"
  19. }
  20. }
  21. ,
  22. t.ascp = e
  23. }(window, document),

python获取as和cp值的代码如下:(代码参考blog:https://www.cnblogs.com/xuchunlin/p/7097391.html)

  1. def 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数据的,
  32. import requests
  33. import json
  34. from openpyxl import Workbook
  35. import time
  36. import hashlib
  37. import os
  38. import datetime
  39. start_url = 'https://www.toutiao.com/api/pc/feed/?category=news_hot&utm_source=toutiao&widen=1&max_behot_time='
  40. url = 'https://www.toutiao.com'
  41. headers={
  42. 'user-agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'
  43. }
  44. cookies = { 'tt_webid':'6649949084894053895'} # 此处cookies可从浏览器中查找,为了避免被头条禁止爬虫
  45. max_behot_time = '0' # 链接参数
  46. title = [] # 存储新闻标题
  47. source_url = [] # 存储新闻的链接
  48. s_url = [] # 存储新闻的完整链接
  49. source = [] # 存储发布新闻的公众号
  50. media_url = { } # 存储公众号的完整链接
  51. def get_as_cp(): # 该函数主要是为了获取as和cp参数,程序参考今日头条中的加密js文件:home_4abea46.js
  52. zz = { }
  53. now = round(time.time())
  54. print(now) # 获取当前计算机时间
  55. e = hex(int(now)).upper()[2:] #hex()转换一个整数对象为16进制的字符串表示
  56. print('e:', e)
  57. a = hashlib.md5() #hashlib.md5().hexdigest()创建hash对象并返回16进制结果
  58. print('a:', a)
  59. a.update(str(int(now)).encode('utf-8'))
  60. i = a.hexdigest().upper()
  61. print('i:', i)
  62. if len(e)!=8:
  63. zz = { 'as':'479BB4B7254C150',
  64. 'cp':'7E0AC8874BB0985'}
  65. return zz
  66. n = i[:5]
  67. a = i[-5:]
  68. r = ''
  69. s = ''
  70. for i in range(5):
  71. s= s+n[i]+e[i]
  72. for j in range(5):
  73. r = r+e[j+3]+a[j]
  74. zz ={
  75. 'as':'A1'+s+e[-3:],
  76. 'cp':e[0:3]+r+'E1'
  77. }
  78. print('zz:', zz)
  79. return zz
  80. def getdata(url, headers, cookies): # 解析网页函数
  81. r = requests.get(url, headers=headers, cookies=cookies)
  82. print(url)
  83. data = json.loads(r.text)
  84. return data
  85. def savedata(title, s_url, source, media_url): # 存储数据到文件
  86. # 存储数据到xlxs文件
  87. wb = Workbook()
  88. if not os.path.isdir(os.getcwd()+'/result'): # 判断文件夹是否存在
  89. os.makedirs(os.getcwd()+'/result') # 新建存储文件夹
  90. filename = os.getcwd()+'/result/result-'+datetime.datetime.now().strftime('%Y-%m-%d-%H-%m')+'.xlsx' # 新建存储结果的excel文件
  91. ws = wb.active
  92. ws.title = 'data' # 更改工作表的标题
  93. ws['A1'] = '标题' # 对表格加入标题
  94. ws['B1'] = '新闻链接'
  95. ws['C1'] = '头条号'
  96. ws['D1'] = '头条号链接'
  97. for row in range(2, len(title)+2): # 将数据写入表格
  98. _= ws.cell(column=1, row=row, value=title[row-2])
  99. _= ws.cell(column=2, row=row, value=s_url[row-2])
  100. _= ws.cell(column=3, row=row, value=source[row-2])
  101. _= ws.cell(column=4, row=row, value=media_url[source[row-2]])
  102. wb.save(filename=filename) # 保存文件
  103. def main(max_behot_time, title, source_url, s_url, source, media_url): # 主函数
  104. for i in range(3): # 此处的数字类似于你刷新新闻的次数,正常情况下刷新一次会出现10条新闻,但夜存在少于10条的情况;所以最后的结果并不一定是10的倍数
  105. ascp = get_as_cp() # 获取as和cp参数的函数
  106. demo = getdata(start_url+max_behot_time+'&max_behot_time_tmp='+max_behot_time+'&tadrequire=true&as='+ascp['as']+'&cp='+ascp['cp'], headers, cookies)
  107. print(demo)
  108. # time.sleep(1)
  109. for j in range(len(demo['data'])):
  110. # print(demo['data'][j]['title'])
  111. if demo['data'][j]['title'] not in title:
  112. title.append(demo['data'][j]['title']) # 获取新闻标题
  113. source_url.append(demo['data'][j]['source_url']) # 获取新闻链接
  114. source.append(demo['data'][j]['source']) # 获取发布新闻的公众号
  115. if demo['data'][j]['source'] not in media_url:
  116. media_url[demo['data'][j]['source']] = url+demo['data'][j]['media_url'] # 获取公众号链接
  117. print(max_behot_time)
  118. max_behot_time = str(demo['next']['max_behot_time']) # 获取下一个链接的max_behot_time参数的值
  119. for index in range(len(title)):
  120. print('标题:', title[index])
  121. if 'https' not in source_url[index]:
  122. s_url.append(url+source_url[index])
  123. print('新闻链接:', url+source_url[index])
  124. else:
  125. print('新闻链接:', source_url[index])
  126. s_url.append(source_url[index])
  127. # print('源链接:', url+source_url[index])
  128. print('头条号:', source[index])
  129. print(len(title)) # 获取的新闻数量
  130. if __name__ == '__main__':
  131. main(max_behot_time, title, source_url, s_url, source, media_url)
  132. savedata(title, s_url, source, media_url)

在这里插入图片描述

发表评论

表情:
评论列表 (有 0 条评论,1272人围观)

还没有评论,来说两句吧...

相关阅读

    相关 爬虫--今日

    1、分析今日头条   在看头条的时候可以发现展示出来的页面的数据都是一些封装过的js代码或者css代码,所以这时候就需要考虑页面的数据是不是封装在cookie里面了   回

    相关 Python新闻网数据

    前言 本文的文字及图片来源于网络,仅供学习、交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理。 PS:如有需要Python学习资料的小伙伴可以加点击下方链接