java爬虫系列(五)——今日头条文章爬虫实战
文章目录
- 项目源码
- 爬虫目标
- 爬虫设计思路
- 爬取方式
- 动态解析网页方式爬取
- 解析接口方式爬取
- 解析思路
- 破解入口
- 接口对比
- 破解加密参数
- 参数生成方式
- 解析js
- 分析接口返回值
- 解析原文地址
- java项目解析
- 基本功能
- 队列和线程池
- 操作界面——swagger2
- 总结
- 补充
- 同系列文章
项目源码
https://github.com/a252937166/toutiaocrawler.git
爬虫目标
爬取某一头条号下面所有文章。
爬虫设计思路
爬取方式
动态解析网页方式爬取
之前介绍过使用webdriver
的方式爬取网页内容,这样做的话好处非常明显,只需要考虑如何解析网页的element
标签就行了,当然弊端也非常明显,就是效率不高。
解析接口方式爬取
没遇到反爬手段逆天的网页,我一般不推荐使用webdriver
的方式,作为一名技术人员,始终要把项目性能放到第一位,所以这次的项目我选择使用破解今日头条接口的方式去拿取他们的文章。
解析思路
破解入口
以台海网为例,一般大型平台都会有pc和H5两种网页。
pc:https://www.toutiao.com/c/user/50502347096/#mid=50502347096
图(1)
h5:http://m.toutiao.com/profile/50502347096/#mid=50502347096(切换到文章的TAB)
图(2)
由Network
的信息可以得到两个文章接口:
pc:
https://www.toutiao.com/c/user/article/?page_type=1&user_id=50502347096&max_behot_time=0&count=20&as=A1B57ACB48A9D4F&cp=5AB8F92DD4CFBE1&_signature=NVHtvxAab.D7OmttJlHb-zVR7a
h5:
https://www.toutiao.com/pgc/ma/?page_type=1&max_behot_time=&uid=50502347096&media_id=50502347096&output=json&is_json=1&count=20&from=user_profile_app&version=2&as=A125DA2BD89A381&cp=5AB81AE3C8116E1&callback=jsonp3
接口对比
很明显,pc端的接口比h5的接口多一个_signature
参数,我私下尝试过破解_signature
的生成方法,结果发现异常复杂,我的前端水平根本搞不定,方法是window.TAC.sign
,有兴趣的同学可以去试试。
图(3)
无奈只能选择h5的接口了,现在只需要破解as
和cp
两个参数就行了。
破解加密参数
参数生成方式
第一部当然是找参数怎么生成的,很遗憾,这一步没有捷径,只能复制好as
和cp
,去每一个js
文件里面匹配,需要一点耐心。
图(4)
解析js
格式化该方法:
!function(t) {var i = {};i.getHoney = function() {var t = Math.floor((new Date).getTime() / 1e3), i = t.toString(16).toUpperCase(), e = md5(t).toString().toUpperCase();if (8 != i.length)return {as: "479BB4B7254C150",cp: "7E0AC8874BB0985"};for (var s = e.slice(0, 5), o = e.slice(-5), n = "", a = 0; 5 > a; a++)n += s[a] + i[a];for (var l = "", r = 0; 5 > r; r++)l += i[r + 3] + o[r];return {as: "A1" + n + i.slice(-3),cp: i.slice(0, 3) + l + "E1"}},t.ascp = i
}(window, document)
不算太难,一个简单的MD5
加密方式,转成java
方法也很简单:
public static Map<String,String> getAsCp(){String as = "479BB4B7254C150";String cp = "7E0AC8874BB0985";int t = (int) (new Date().getTime()/1000);String e = Integer.toHexString(t).toUpperCase();String i = DigestUtils.md5DigestAsHex(String.valueOf(t).getBytes()).toUpperCase();if (e.length()==8) {char[] n = i.substring(0,5).toCharArray();char[] a = i.substring(i.length()-5).toCharArray();StringBuilder s = new StringBuilder();StringBuilder r = new StringBuilder();for (int o = 0; o < 5; o++) {s.append(n[o]).append(e.substring(o,o+1));r.append(e.substring(o+3,o+4)).append(a[o]);}as = "A1" + s + e.substring(e.length()-3);cp = e.substring(0,3) + r + "E1";}Map<String,String> map = new HashMap<>();map.put("as",as);map.put("cp",cp);return map;}
分析接口返回值
media_id:该媒体ID
message:是否成功
next.max_behot_time:下一页的请求参数
has_more:是否有下一页
data.article_url:文章的html地址
其他参数都不重要了,这里并没有直接返回文章的内容,下一步就是去原文地址爬取文章内容了。
解析原文地址
基本是个静态网页,直接提取标签里面的内容就行了。
java项目解析
基本功能
为了方便,我使用spring boot框架,设计成了一个web项目,以访问接口的方式启动或者停止爬虫。
队列和线程池
因为是接口的方式启动爬虫,所以不可能等10多万个爬虫任务结束之后再返回成功,只能异步执行任务,所以需要线程池。
光有线程池还不够,几十万甚至更多的任务全部甩给线程池,显然不是一个好的选择。所以这里就需要java
的Queue
,我选择的是LinkedBlockingDeque
,不过最后还是没用到双端的特性,所以使用LinkedBlockingQueue
是一样的,把所有需要爬取的任务先放入Queue
队列中,开始爬取的时候再从里面拿去地址,这样就可简单的解决高并发的问题。
如果任务量特别大,而且有对详细日志的需求,可以选择换成kafka
。
操作界面——swagger2
使用postman
发送请求还是不太方便,还要填地址之类的,我考虑有个前端界面来操作就最好了,但是前端水平有限,不想花太多时间写,所以选择了集成swagger2
。
打开http://127.0.0.1:9091/swagger-ui.html#/
图(5)
图(6)
一看就知道怎么用了,我就不多介绍了,有兴趣的同学,可以根据这五个接口,写一个前端界面,一个针对头条号的爬虫就算完成了。
图(7)
总结
爬虫最难的地方其实并不在代码上,而在于对爬取网页的分析上,比如制定爬取方式,攻破对方的反爬手段等等,需要一些耐心和分析能力,所谓熟能生巧,最主要的还是要多尝试,累计经验。
补充
经网友提示发现,每个mid下的内容页的结构方式略有不同,本文中的mid的内容页是静态页面,所以使用Jsoup
解析,另外有些mid
,比如1558737777313793
(AI财经社),它的内容页是动态页面,我使用的是正则匹配获取对应数据,示例在dev1.0
分支上,大家可以借鉴一下,掌握这两种解析方式,解析其他mid
都大同小异了。
同系列文章
java爬虫系列(一)——爬虫入门
java爬虫系列(二)——爬取动态网页
java爬虫系列(三)——漫画网站爬取实战
java爬虫系列(四)——动态网页爬虫升级版
java爬虫系列(五)——今日头条文章爬虫实战相关推荐
- 今日头条文章爬虫实战
原 java爬虫系列 今日头条文章爬虫实战 置顶 2018年03月26日 16:55:31 Mr_OOO 阅读数:3868更多 <div class="tags-box space&q ...
- Python编写今日头条文章爬虫,轻松发布!
在当今的信息时代,新闻资讯是人们获取信息的重要途径之一.而作为国内领先的新闻资讯平台,今日头条每天都会推送大量的新闻内容.对于媒体从业者来说,想要获取最新.最全面的新闻资讯,就需要使用到网络爬虫技术. ...
- python爬虫爬取今日头条_Python爬虫实战入门五:获取JS动态内容—爬取今日头条...
之前我们爬取的网页,多是HTML静态生成的内容,直接从HTML源码中就能找到看到的数据和内容,然而并不是所有的网页都是这样的. 有一些网站的内容由前端的JS动态生成,由于呈现在网页上的内容是由JS生成 ...
- java spring+mybatis整合实现爬虫之《今日头条》搞笑动态图片爬取
java spring+mybatis整合实现爬虫之<今日头条>搞笑动态图片爬取(详细) 原文地址原博客地址 先上效果图 抓取的动态图: 数据库: 一.此爬虫介绍 今日头条本身就是做爬虫的 ...
- 博客搬家系列(六)-爬取今日头条文章
博客搬家系列(六)-爬取今日头条文章 一.前情回顾 博客搬家系列(一)-简介:https://blog.csdn.net/rico_zhou/article/details/83619152 博客搬家 ...
- java爬取今日头条文章
闲来无事,写了个爬虫爬取今日头条的文章信息,然后使用ECharts展示出统计结果. 那么怎样爬取今日头条的信息呢? 首先,分析头条页面 文章是通过ajax获取的 所以要找到调用的url,然后跟踪代码查 ...
- python3 爬取今日头条文章(巧妙避开as,cp,_signature)
使用环境: python3 scrapy win10 爬取思路 (一)关于as.cp的生成与_signature的想法 对于今日头条的爬虫,网上搜索出来的文章大多是基于崔庆才(通过搜索爬取美女街拍的方 ...
- 基于python的今日头条文章抓取内含signature算法
基于python的今日头条文章抓取内含signature算法 扫二维码添加微信 备注:爬虫 , 拉你进爬虫交流群 或许你会成为第一个加群的人~ 刚有的创群想法! 1. 简单文字描述头条爬虫注意点 由于 ...
- (android高仿系列)今日头条 --新闻阅读器 (一)
在模仿中循序渐进,以程序员角度去看待每一个APP是如何实现的,它有什么优缺点,并从中提升自己. 之前发现很多人在群里面.论坛上求网易新闻客户端的源码,之后我就去下了个网易新闻客户端和今日头条新闻客户端 ...
最新文章
- 图示评审技术_编制清单报价最需要施工技术课程中的哪些知识?
- 教你学会七种维护服务器安全最佳技巧
- jquery操作滚动条滚动到指定位置
- 《iOS9开发快速入门》——第2章,第2.1节Xcode 7.0的新特性
- 菜鸟python_菜鸟爱Python第1期:Python发展史?对Python最深刻的解读
- 刘知远老师为你解读:自然语言理解到底难在哪儿?
- LX04 小米触屏音箱刷机教程
- 同济大学计算机专业考研的教材,同济大学电子信息(计算机与智能技术)专业考研参考书目-指定教材-辅导资料...
- 用命令将FAT32格式磁盘转换为NTFS格式
- Simulink中利用Powergui进行FFT分析,但是信号源始终为空
- 【Leetcode刷题篇】Leetcode714 买卖股票的最佳时机含手续费
- 饭店点餐系统之系统网络结构
- python中摄氏度华氏度相互转换
- 微信公众号开发教程(六)获取微信用户信息-网页授权
- Qt:C++应用程序开发入门
- 【单片机】唯一设备ID UID固件加密
- linux执行rm -rf /*命令后的效果原来是这样
- 【newman】postman生成漂亮的测试报告
- mysql查看主机名_mysql怎么看主机名
- 用m1 pro的MacBook Pro,安装 Anaconda arm 图形版
热门文章
- 《所谓会说话,就是会换位思考》总结
- python提取微信聊天语音_GitHub - dennischancs/wechat-asr: 微信语音批量转文字 python编写 用百度智能云短语音识别API实现 windows下的使用...
- linux ubuntu系统 ERROR 1045 (28000): Access denied for user ‘root‘@‘localhost‘ (using password: YES)数据
- cas112-27-6|三乙二醇/二缩三乙二醇/三甘醇|三乙二醇 透明液体
- C# 语法糖(Syntactic sugar)
- webfont.woff2和webfont.woff下载超时报404错误
- windows下用Mingw64编译qtw3d
- 7 款优秀 Markdown 编辑工具推荐
- sqlite_win10
- Linux系统网络环境配置(初学者必看)!!