*相关背景:本篇文章是学习了崔庆才老师的爬虫实践课程后的一篇学习笔记,更多相关的信息请到崔老师博客。
崔庆才的个人博客:https://ask.hellobi.com/blog/id-cuiqingcai*
目标:
1.通过一个大V用户开始,通过递归抓取粉丝列表和关注列表,实现知乎所有用户的详细信息的抓取。
2.将抓取到的结果存储到MongoDB,并进行去重操作。
分析思路:
众所周知,在知乎上面每个人都会有关注列表以及粉丝列表,如果我们从一个大V开始,首先可以获取他的个人信息,然后我们获取他的粉丝列表和关注列表,然后遍历列表中的每一个用户,进一步抓取每一个用户的信息还有他们各自的粉丝列表和关注列表,然后再进一步遍历获取到的列表中的每一个用户,进一步抓取他们的信息和关注粉丝列表,循环往复,不断递归,这样就可以做到一爬百,百爬万,万爬百万,通过社交关系自然形成了一个爬取网,这样就可以爬到所有的用户信息了。
创建项目:
scrapy startproject zhihuuser
创建爬虫
cd zhihuuser
scrapy genspider zhihu www.zhihu.com
禁止ROBOTSTXT_OBEY
打开settings.py文件,将ROBOTSTXT_OBEY修改为False
ROBOTSTXT_OBEY = False
它默认为True,就是要遵守robots.txt 的规则,那么 robots.txt 是个什么东西呢?
通俗来说, robots.txt 是遵循 Robot 协议的一个文件,它保存在网站的服务器中,它的作用是,告诉搜索引擎爬虫,本网站哪些目录下的网页 不希望 你进行爬取收录。在Scrapy启动后,会在第一时间访问网站的 robots.txt 文件,然后决定该网站的爬取范围。
当然,我们并不是在做搜索引擎,而且在某些情况下我们想要获取的内容恰恰是被 robots.txt 所禁止访问的。所以,某些时候,我们就要将此配置项设置为 False ,拒绝遵守 Robot协议 !
所以在这里设置为False。当然可能本次爬取不一定会被它限制,但是我们一般来说会首先选择禁止它。
设置UA
打开settings.py文件,取消DEFAULT_REQUEST_HEADERS的注释,加入如下的内容:
DEFAULT_REQUEST_HEADERS = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko)Chrome/56.0.2924.87 Safari/537.36'
}
设置OA
它是Open Authorization的缩写。
OAUTH_token:OAUTH进行到最后一步得到的一个“令牌”,通过此“令牌”请求,就可以去拥有资源的网站抓取任意有权限可以被抓取的资源。
DEFAULT_REQUEST_HEADERS = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36',
'authorization': 'oauth c3cef7c66a1843f8b3a9e6a1e3160e20',
}
爬取步骤
以轮子哥为例:https://www.zhihu.com/people/excited-vczh/following
我在这里找到了关注列表的URL以及相关参数include,offset,limit.
构造动态URL
user_url = 'https://www.zhihu.com/api/v4/members/{user}?include={include}'
follows_url='https://www.zhihu.com/api/v4/members/{user}/followees?include={include}&offset={offset}&limit={limit}'
处理需要保存的信息
在items里新声明一个UserItem
from scrapy import Item, Field
class UserItem(Item):
# define the fields for your item here like:
id = Field()
name = Field()
avatar_url = Field()
headline = Field()
description = Field()
url = Field()
url_token = Field()
gender = Field()
cover_url = Field()
type = Field()
badge = Field()
answer_count = Field()
articles_count = Field()
commercial_question_count = Field()
favorite_count = Field()
favorited_count = Field()
follower_count = Field()
following_columns_count = Field()
following_count = Field()
pins_count = Field()
question_count = Field()
thank_from_count = Field()
thank_to_count = Field()
thanked_count = Field()
vote_from_count = Field()
vote_to_count = Field()
voteup_count = Field()
following_favlists_count = Field()
following_question_count = Field()
following_topic_count = Field()
marked_answers_count = Field()
mutual_followees_count = Field()
hosted_live_count = Field()
participated_live_count = Field()
locations = Field()
educations = Field()
employments = Field()
在解析方法里面我们解析得到的response内容,然后转为json对象,然后依次判断字段是否存在
result = json.loads(response.text)
item = UserItem()
for field in item.fields:
if field in result.keys():
item[field] = result.get(field)
yield item
得到item后通过yield返回就好了。
这样保存用户基本信息就完成了。
接下来我们还需要在这里获取这个用户的关注列表,所以我们需要再重新发起一个获取关注列表的request
在parse_user后面再添加如下代码:
yield Request(
self.follows_url.format(user=result.get('url_token'), include=self.follows_query, limit=20, offset=0),
self.parse_follows)
parse_follows
接下来我们处理一下关注列表,首先也是解析response的文本,然后要做两件事:
通过关注列表的每一个用户,对每一个用户发起请求,获取其详细信息。
处理分页,判断paging内容,获取下一页关注列表。
小结
通过以上的spider,我们实现了如上逻辑:
start_requests方法,实现了第一个大V用户的详细信息请求还有他的粉丝和关注列表请求。
parse_user方法,实现了详细信息的提取和粉丝关注列表的获取。
paese_follows,实现了通过关注列表重新请求用户并进行翻页的功能。
paese_followers,实现了通过粉丝列表重新请求用户并进行翻页的功能。
加入pipeline
来源:CSDN
作者:will-Zhan
链接:https://blog.csdn.net/qq_40717846/article/details/78950519