上一个项目完成的时间是7月14日,今天是8月30日,已经过去了一个半月,这段时间做了第二个,学了一个半月的爬虫。
代码写了400多行,目前为止单个项目写的最多的代码。。
上班之前就有预感会做关于爬虫的东西,果不其然(捂脸)…
其实上学的时候学爬虫,特别是学scrapy,我的内心是拒绝的。因为scrapy看起来是个很臃肿的框架,上学那个阶段,并没有什么项目需要用到它,用用Request和BS4已经完全够用了。之前那个项目在维基百科上抓取subcategory时,就是用的Request和BS4,抓了1000多个页面,爬虫依然可以跑,这已经完全够了。
(部分内容可以略过)
2018.12.11更新
各位上来就 “这个项目要怎么跑通啊?” “接口不对啊,怎么调啊?” 的朋友,你问这种问题的时候,给我转个大点红包,我教你跑通,也算是知识付费。
但是你要是什么都不懂就想不劳而获,去找其他人吧,邮件我不会回的。
欢迎那些交流具体技术的人来邮件,比如说“splash-scrapy 在国内怎么设置代理” 这种问题我会回复。
关于facebook
现在公司要给我的任务是抓facebook上,搜索一个keyword,关于这个keyword的所有publick post,包括内容,时间,评论的人,点赞的人,分享的人,具体结构如下:
{
"task": task name,
"type": "facebook_post",
"url": default None,
"keyword": search keyword,
"timestamp": spider crawls timestamp,
"post_data":[{
"post_information":{
"post_from_user": post from user name,
"post_from_user_id": post from user id,
"post_id": post's id,
"post_type": "posts", "photos", "videos"
"post_content": post's content,
"post_link": post's article link url,
"post_time": post created time,
"post_likes_number": the number of post who likes it,
"post_shares_number": the number of post who share it,
"post_comments_number": the number of post who comment it
},
"post_likes":
[
{
"id": user's account id,
"name": user's name
},
...],
"post_shares":
[
{
"id": user's account id,
"name": user's name
},
...],
"post_comments":
[
{
"id": user's account id,
"name": user's name
"comment_content": comment's content
},
...]
},
...]
}
关于这个结构我说一下,facebook提供了一个官方的API, 叫Graph API explorer,是一个很强大的API,在网页上你可以看到的所有公开信息,在这个API里都可以请求到。但是有两个限制:
- rate limit,好像是一天最多只有4500次请求,具体数字我忘记了。
- access token,这个API有个token,是短期的,2个小时就会过期,需要重新请求。也可以按照官方的方法换成长期的access token,有效期是2个月。但是这怎么能满足我呢,所以我申请了一个永久的access token,具体方法见 :
申请facebook永久access token的方法。
Graph API具体用法参照facebook 官方文档。
关于这次爬虫用到的技术
关于scrapy 框架
熟悉scrapy框架就用了两三天,因为这个以前还真没接触过,那段时间是最蛋疼的一段时间了。但是,学一个框架最好的学习方法就是看官方文档。
用爬虫做大型的项目真的应该全面拥抱scrapy。这里说心得体会,就两点觉得很有必要说一下:
- 熟悉到底是要return还是yield,return和yield不对的错误会很头疼的;
- 理解你的response.status,这里对各种状态码的理解对debug有大用。
代码流程
- 登录部分,resquest登录页面,用scrapy.formresquest登录,如果登录失败退出爬虫,需要手动检查原因(facebook账号登录异常时有手机验证机制);
- 构造search keyword url,直接进入public post页面,利用splash进行页面的JS渲染,返回第一个页面首先出现的几个post,F12打开开发者工具,研究下拉时的页面数据请求,观察源代码,构造出页面数据请求,这个就相当于不断下拉,刷新出新的post的动作。(这个等下要详细讲)
- 抓取每个post的ID,利用Graph API请求出每个post的likes,comments,shares的user‘s name and ID, 返回item。
关于IP代理的处理
这次代码直接挂在了亚马逊的服务器上,所以没有怎么管这个,但是在本地测试的时候,不要以为换IP就不会被block掉,naive,这么简单的策略骗过不需要登录的站点还可以,你用一个账号不断的换IP登录,你的账号很快就被封掉了,特别是这种国外的社交网站,涉及到个人隐私的。
正确的办法是,将一个IP对应一个账号,并发抓取(我这里由于项目的任务调度问题,没有并发抓取),间隔时间设置大一些。当然API对resquest速度没有要求,使劲造。如果是纯网页的抓取,建议30s左右抓取一个页面,如果碰到等厉害的,就要用模拟JS动作了(等会讲)。
关于登录facebook
对于登录来说,facebook登录页面也没什么好讲的,看scary官方文档,就一个请求就可以自动填表了,代码如下:
return FormRequest.from_response(
response,
url = self.login_url,
formid = "login_form",
formdata = {
"email": self.login_user,
"pass": self.login_pass
},
callback = self.after_login
)
formdata里的参数就是登录的username和password。
整个爬虫中,登录最重要一点