Python网络爬虫入门(五)—— 巧用抓包,爬遍SCU玻璃杯事件所有神回复

浏览: 1756

最近我川又搞事情了

然后info又炸了,,,

据说最开始是这样的:

5247646-f15fea5c24695e18.png

然后是这样的

5247646-faccaf5a2417f28e.png

然后一发不可收拾了,校园各处不约而同响起了摔杯的声音,微信微博朋友圈qq空间,特么也全是玻璃碎片啊!!! 

image.png

image.png


image.png

(详情也可见scu官方微信 :http://mp.weixin.qq.com/s?src=3&timestamp=1490410781&ver=1&signature=yC6sD9GWkafISfsQYoQA57qlf0UA2HU6xCEqGq6fUMDy1KY-XGp3uoPmhRNOgGIkLuP4yG25bBy-dQuPADd14mJ7q-w-HG1S0sxo*rbyTb91rludqraUqThJ673CxrJAXl1oN-6MGYULf-8Fur-40A**hSFGONgoRmQslEb2Ij4= ) 

摔碎一个玻璃杯,炸出我川多少潜伏的优秀段子手! 
据说后面还引来了武大、浙大等各校园的观光团。

如此空前盛况怎能错过,于是宝宝决定搞点事情。。。

怎么可能又摔杯!!

(话说我的杯子是塑料的好吧,还是PET的呢) 
额,好像有点什么不对。。。 

image.png

不胡扯了,上Info爬取玻璃杯事件所有热门神回复,嗯先立个flag。

一、过程

先搜了一下网页版的scuinfo

image.png

首先初步观察分析

点击一看画面简洁却不失清新,也是瀑布流,需要下拉刷新的那种。 
再看一下源码,一下就懵了,什么关键数据也没有呀,用pycharm获取果然也是一样。可以看出采用的JavaScriptjQuery,有点难办了。 

image.png

image.png


最先想到是用selenium定位,然后截屏什么的,结果连续报错:无法定位到元素。胡乱百度了半天,没有一丝收获。 

都快洗洗睡了,最后想到之前在知乎上看到有人用的抓包,回去翻了相关帖子,峰回路转。这里感谢这个教程。 

image.png

看完这一篇,打开浏览器开发者工具,切换至network抓包。 

image.png

点开看到每个评论真实URL地址,估计每一个评论皆有个特殊的id 

image.png

将URL粘贴至浏览器 

image.png

原来所有信息都在这个包里面了!!! 

URL中的id值也在这里了,所以好办了。 

找到原帖、新帖id,循环构造URL并用requests或取。 

下拉刷新找传说中那个原帖,还真被我找到,原帖id=131599 

image.png

接着就是获取最新帖子id

特么我在这又兜圈了!因为帖子是随时更新的,想着可以一试selenium模拟浏览器。结果又定位失败,搞了好久于是决定先搁置。 

先去获取和处理数据

仔细观察数据,发现string格式的,里面是一个dict,dict里面data又是一个dict。“如何将string格式转变为dict”,想了许久又去百度了,搜到一靠谱答案。测试可用。 

image.png

后面才发现这一堆原来是json格式的(回去翻基础,难怪如此熟悉),又将eval()换成json.loads()。基础不牢地动山摇啊。。。

从data中提取发言、评论、点赞等,再从发言中提取所有关于玻璃杯事件的消息。决定匹配正则,可是“如何在一堆中文中匹配中文关键词”? 
之前都是在标签中提取数据,情况少见真的把我难住了,编码问题让人头痛。 
滚去睡觉,第二天又去百度,统统的不行啊。

静下心想了想,pycharm获取的数据本来就是Unicode格式的,只要html不转为utf-8,然后将中文关键词在IDE中转为Unicode格式,不就可以匹配的上了么? 
事实如此! 
正则是这样,四个关键词:“玻璃”、“杯”、“摔”、“观光”

    pattern=re.compile(u'\u73bb\u7483|\u676f|\u6454|\u89c2\u5149',re.S)
items=re.search(pattern,body)

我以为接下来就是美滋滋地等待一堆数据,结果又报错: 

image.png

这个list什么鬼?于是回去查看。原来data是空的list,估计是已经删除的评论,所以data为None。再试了下不存在的id,比如id=137945,同样如此。

image.png

改了下代码,可以运行。

 if not isinstance(data, list):
xxx(内容)
else:
print 'None'

然后返回去获取新评论URL

又想了试了很久,曾经也想过最后打出10个或以上的None然后break结束,但是发现代码无法实现,只能手动结束,心想这算什么程序,不行不行。然后很无聊又到info上看帖去了(MDZZ。。。)后来再打开network发呆了下,想到了。既然打开一页可以抓包,那么刷新看新评论肯定也可以呀。

就不放图了,和之前一样,每次刷新页面便会请求 
URL=’http://www.scuinfo.com/api/posts?pageSize=15‘, 
目测15就是不用刷新时一页总评论数(滑动鼠标验证了下果然是) 
这么简单,为什么之前没想到啊啊啊!(简直想表演胸口碎大石) 

筛选热门100条神回复

最初想的是前面已经获得所有数据了,先每一项的发言、点赞、评论保存入一个list中,多个list放到一个大的list中(暂且叫Container)。 
可提取的时候麻烦了,我想按照点赞数排列container中所有的list,怎么办呀。

试了许久不行,上百度搜“list集合中如何按照某一个属性排序”,基本无果。 
心想这是给自己挖了个坑呀,于是改用dict来装。 
反正在这里绕了好久,试了很多次比如用lambda呀之类, 
最后终于解决了,csdn上的一个博文,真是前人栽树后人乘凉啊。

 def getSort(self):
container=self.getDetail()
print u'\n',u'将人气最高的前100条打印如下:'
container.sort(key=lambda k:k.get('comment',0))
container.sort(key=lambda k:k.get('like',0),reverse=True)
for index,r in enumerate(container):
print u'\n\n序号:',index+1, u'\n发言:',r['body'],u'\n点赞:' ,r['like'],u'评论',r['comment']

原本以为到这里就结束了,结果运行过程中又出新bug了 

(真怀疑自己是不是招bug体质哎。。。):

image.png

没见过,又百度去,原来是这么个回事,解决了: 

image.png

二、结果和代码

image.png

数据是昨天的。今天又运行了程序,发现已经不止1200了 

下面就是最热门是评论了 

5247646-2f0abc0fb5ad7868.png

5247646-48f1ae4adface8db.png

爬取的数据实在是多,象征性放前20条

想看完整版100条的可以去我微博

http://weibo.com/u/5690935322?refer_flag=1005055010_&is_all=1

源码在Github上

https://github.com/LUCY78765580/Python-web-scraping/blob/master/BoLiBei.py 


终于搞定一切,接下来干点什么好? 

image.png

这一次写爬虫,遇到不少问题,总结如下: 
1、破解javascript动态网页(抓包) 
2、json格式数据解析(json.loads()) 
3、在中文中匹配特定中文的正则表达式(先将关键词转换) 
4、多个list按照某一属性排序问题 
(lambda函数和enumerate迭代器) 
5、http连接太多没有关闭报错的问题

回去补补基础。 
不过算是学会了抓包,这种东西简直有如神器呀。 
嘿嘿,本篇就是这样啦~

推荐 4
本文由 waking_up88688 创作,采用 知识共享署名-相同方式共享 3.0 中国大陆许可协议 进行许可。
转载、引用前需联系作者,并署名作者且注明文章出处。
本站文章版权归原作者及原出处所有 。内容为作者个人观点, 并不代表本站赞同其观点和对其真实性负责。本站是一个个人学习交流的平台,并不用于任何商业目的,如果有任何问题,请及时联系我们,我们将根据著作权人的要求,立即更正或者删除有关内容。本站拥有对此声明的最终解释权。

0 个评论

要回复文章请先登录注册