Srapy 爬取知乎用户信息
今天用scrapy框架爬取一下所有知乎用户的信息。道理很简单,找一个知乎大V(就是粉丝和关注量都很多的那种),找到他的粉丝和他关注的人的信息,然后分别再找这些人的粉丝和关注的人的信息,层层递进,这样下来,只要有关注的人或者有粉丝的账号,几乎都能被爬下来。话不多说,进入正题。
1、首先按照上篇博客的介绍,先建立项目,然后建一个spider文件,scrapy genspider zhihu www.zhihu.com.
进入settings.py,修改内容 ROBOTSTXT_OBEY = False,意思是知乎网页中禁止爬取的内容也可以爬的到。
再添加一个User_agent,因为知乎是通过浏览器识别的,否则知乎会禁止爬取
DEFAULT_REQUEST_HEADERS = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'en',
'User-agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'
}
2、进入知乎网页页面,搜索一个大V,这里我用的是vczh,这个账号的关注量和粉丝都特别多。
改写zhihu.py的内容如下:
from scrapy import Request,Spider class ZhihuSpider(Spider):
name = 'zhihu'
allowed_domains = ['www.zhihu.com']
start_urls = ['http://www.zhihu.com/'] def start_requests(self): # zhihu.py 会先调用 start_requests 函数
url = 'https://www.zhihu.com/api/v4/members/ji-he-61-7?include=allow_message%2Cis_followed%2Cis_following%2Cis_org%2Cis_blocking%2Cemployments%2Canswer_count%2Cfollower_count%2Carticles_count%2Cgender%2Cbadge%5B%3F(type%3Dbest_answerer)%5D.topics'
yield Request(url,callback=self.parse) def parse(self, response):
print(response.text)
随便找一个vczh关注的人,把他的Request URL拿过来请求一下,发现正常输出了结果,说明是能够获取 vczh 自己的信息的。

将URL换成 followees(vczh关注的人) 的Request URL,同样输出了正确的结果,说明 vczh 关注的人的信息也能正常输出。
经过观察发现,每个用户详细信息的 URL 只有 url_token 不同,因此分别构造 user_url 和 follows_url:
class ZhihuSpider(Spider):
name = 'zhihu'
allowed_domains = ['www.zhihu.com']
start_urls = ['http://www.zhihu.com/'] start_user = 'excited-vczh' user_url = 'https://www.zhihu.com/api/v4/members/{user}?include={include}'
user_query = 'allow_message,is_followed,is_following,is_org,is_blocking,employments,answer_count,follower_count,articles_count,gender,badge[?(type=best_answerer)].topics' follows_url = 'https://www.zhihu.com/api/v4/members/{user}/followees?include={include}&offset={offset}&limit={limit}'
follows_query = 'data[*].answer_count,articles_count,gender,follower_count,is_followed,is_following,badge[?(type=best_answerer)].topics' def start_requests(self):
yield Request(self.user_url.format(user=self.start_user, include=self.user_query),callback=self.parse_user)
yield Request(self.follows_url.format(user=self.start_user, include=self.follows_query, offset=0, limit=20),callback=self.parse_follows) def parse_user(self, response):
result = json.loads(response.text)
item = Zhihu3Item()
for field in item.fields:
if field in result.keys():
item[field] = result.get(field)
yield item def parse_follows(self, response):
results = json.loads(response.text)
if 'data' in results.keys():
for result in results.get('data'):
yield Request(self.user_url.format(user=result.get('url_token'), include=self.user_query),
self.parse_user) if 'paging' in results.keys() and results.get('paging').get('is_end') == False: # 如果当前页不是最后一页
next_page_str = results.get('paging').get('next')
next_page = next_page_str.replace('https://www.zhihu.com/', 'https://www.zhihu.com/api/v4/')
# next_page = next_page_str[0:22] + 'api/v4/' + next_page_str[22:len(next_page_str)] # 这种写法也行
yield Request(next_page, self.parse_follows)
结果正确输出了 vczh 和 他所关注的用户的详细信息。
3、接下来,把 vczh 关注的用户 所 关注的用户的信息输出来:
在 def parse_user(self, response): 函数后添加一句
yield Request(self.follows_url.format(user=result.get('url_token'), include=self.follows_query, offset=0, limit=20),self.parse_follows) 就好了。
4、除了获取用户关注的人以外,还要获取用户的粉丝信息。经观察,发现粉丝信息的 URL 与关注的人的 URL 类似,改写以后的最终版本如下:
class ZhihuSpider(Spider):
name = 'zhihu'
allowed_domains = ['www.zhihu.com']
start_urls = ['http://www.zhihu.com/'] start_user = 'excited-vczh' user_url = 'https://www.zhihu.com/api/v4/members/{user}?include={include}'
user_query = 'allow_message,is_followed,is_following,is_org,is_blocking,employments,answer_count,follower_count,articles_count,gender,badge[?(type=best_answerer)].topics' follows_url = 'https://www.zhihu.com/api/v4/members/{user}/followees?include={include}&offset={offset}&limit={limit}'
follows_query = 'data[*].answer_count,articles_count,gender,follower_count,is_followed,is_following,badge[?(type=best_answerer)].topics' followers_url = 'https://www.zhihu.com/api/v4/members/{user}/followers?include={include}&offset={offset}&limit={limit}'
followers_query = 'data[*].answer_count,articles_count,gender,follower_count,is_followed,is_following,badge[?(type=best_answerer)].topics' def start_requests(self):
yield Request(self.user_url.format(user=self.start_user, include=self.user_query),callback=self.parse_user)
yield Request(self.follows_url.format(user=self.start_user, include=self.follows_query, offset=0, limit=20),callback=self.parse_follows)
yield Request(self.followers_url.format(user=self.start_user, include=self.followers_query, offset=0, limit=20),callback=self.parse_followers) def parse_user(self, response):
result = json.loads(response.text)
item = Zhihu3Item()
for field in item.fields:
if field in result.keys():
item[field] = result.get(field)
yield item yield Request(self.follows_url.format(user=result.get('url_token'), include=self.follows_query, offset=0, limit=20),self.parse_follows)
yield Request(self.followers_url.format(user=result.get('url_token'), include=self.followers_query, offset=0, limit=20),self.parse_followers) def parse_follows(self, response):
results = json.loads(response.text)
if 'data' in results.keys():
for result in results.get('data'):
yield Request(self.user_url.format(user=result.get('url_token'), include=self.user_query),
self.parse_user) if 'paging' in results.keys() and results.get('paging').get('is_end') == False: # 如果当前页不是最后一页
next_page_str = results.get('paging').get('next')
next_page = next_page_str.replace('https://www.zhihu.com/', 'https://www.zhihu.com/api/v4/')
# next_page = next_page_str[0:22] + 'api/v4/' + next_page_str[22:len(next_page_str)] # 这种写法也行
yield Request(next_page, self.parse_follows) def parse_followers(self, response):
results = json.loads(response.text)
if 'data' in results.keys():
for result in results.get('data'):
yield Request(self.user_url.format(user=result.get('url_token'), include=self.user_query),
self.parse_user) if 'paging' in results.keys() and results.get('paging').get('is_end') == False: # 如果当前页不是最后一页
next_page_str = results.get('paging').get('next')
next_page = next_page_str.replace('https://www.zhihu.com/', 'https://www.zhihu.com/api/v4/')
# next_page = next_page_str[0:22] + 'api/v4/' + next_page_str[22:len(next_page_str)] # 这种写法也行
yield Request(next_page, self.parse_followers)
5、将输出的内容保存到MongoDb中
跟上一篇博文类似,在pipeline.py中写入一下内容,直接上代码:
import pymongo class MongoPipeline(object):
def __init__(self, mongo_uri, mongo_db):
self.mongo_uri = mongo_uri
self.mongo_db = mongo_db @classmethod
def from_crawler(cls, crawler):
return cls(
mongo_uri=crawler.settings.get('MONGO_URI'),
mongo_db=crawler.settings.get('MONGO_DB')
) def open_spider(self, spider):
self.client = pymongo.MongoClient(self.mongo_uri)
self.db = self.client[self.mongo_db] def process_item(self, item, spider):
self.db['information'].update({'url_token':item['url_token']},{'$set':item},True)
return item # 根据'url_token'去重,True 表示如果重复就执行刷新操作,如果不重复就执行插入操作 def close_spider(self, spider):
self.client.close()
在settings.py中写入以下代码:
ITEM_PIPELINES = {
'zhihu_3.pipelines.MongoPipeline': 300
}
MONGO_URI='localhost'
MONGO_DB = 'zhihu_3'
运行即可,成功保存到MongoDB中
Srapy 爬取知乎用户信息的更多相关文章
- 基于webmagic的爬虫小应用--爬取知乎用户信息
听到“爬虫”,是不是第一时间想到Python/php ? 多少想玩爬虫的Java学习者就因为语言不通而止步.Java是真的不能做爬虫吗? 当然不是. 只不过python的3行代码能解决的问题,而Jav ...
- 利用 Scrapy 爬取知乎用户信息
思路:通过获取知乎某个大V的关注列表和被关注列表,查看该大V和其关注用户和被关注用户的详细信息,然后通过层层递归调用,实现获取关注用户和被关注用户的关注列表和被关注列表,最终实现获取大量用户信息. 一 ...
- 爬虫(十六):scrapy爬取知乎用户信息
一:爬取思路 首先我们应该找到一个账号,这个账号被关注的人和关注的人都相对比较多的,就是下图中金字塔顶端的人,然后通过爬取这个账号的信息后,再爬取他关注的人和被关注的人的账号信息,然后爬取被关注人的账 ...
- 爬虫实战--利用Scrapy爬取知乎用户信息
思路: 主要逻辑图:
- python3编写网络爬虫22-爬取知乎用户信息
思路 选定起始人 选一个关注数或者粉丝数多的大V作为爬虫起始点 获取粉丝和关注列表 通过知乎接口获得该大V的粉丝列表和关注列表 获取列表用户信息 获取列表每个用户的详细信息 获取每个用户的粉丝和关注 ...
- [Python爬虫] Selenium爬取新浪微博客户端用户信息、热点话题及评论 (上)
转载自:http://blog.csdn.net/eastmount/article/details/51231852 一. 文章介绍 源码下载地址:http://download.csdn.net/ ...
- 使用python scrapy爬取知乎提问信息
前文介绍了python的scrapy爬虫框架和登录知乎的方法. 这里介绍如何爬取知乎的问题信息,并保存到mysql数据库中. 首先,看一下我要爬取哪些内容: 如下图所示,我要爬取一个问题的6个信息: ...
- 第二个爬虫之爬取知乎用户回答和文章并将所有内容保存到txt文件中
自从这两天开始学爬虫,就一直想做个爬虫爬知乎.于是就开始动手了. 知乎用户动态采取的是动态加载的方式,也就是先加载一部分的动态,要一直滑道底才会加载另一部分的动态.要爬取全部的动态,就得先获取全部的u ...
- 【Python项目】爬取新浪微博个人用户信息页
微博用户信息爬虫 项目链接:https://github.com/RealIvyWong/WeiboCrawler/tree/master/WeiboUserInfoCrawler 1 实现功能 这个 ...
随机推荐
- Rocket - debug - TLDebugModuleInner - Abstract Command State Machine
https://mp.weixin.qq.com/s/RcXI8uEHvZHGCvX3DoVR4Q 简单介绍TLDebugModuleInner中处理抽象命令时的状态机. 1. CtrlState 定 ...
- Rocket - tilelink - Xbar
https://mp.weixin.qq.com/s/UXFHYEQaYotWNEhshro68Q 简单介绍Xbar的实现. 1. 基本介绍 用于为Xbar的输入和输出连接生成内 ...
- doReleaseShared源码分析及唤醒后继节点的过程分析
文章结构 源码:对doReleaseShared()方法的源码进行一些注释 使用场景:介绍doReleaseShared()使用位置,及目的 以写锁开始的队列:分析写锁开始得同步等待队列在唤醒后续读锁 ...
- Redis高可用-主从,哨兵,集群
主从复制 Master-Slave主从概念 同时运行多个redis服务端,其中一个作为主(master),其他的一个或多个作为从(slave),主从之间通过网络进行通讯,slave通过复制master ...
- Linux (七)权限控制
个人博客网:https://wushaopei.github.io/ (你想要这里多有) 1. 概述 Linux需要对登录用户读写执行文件.进入目录.查看增删目录内容等操作进行控制,不能任由用户 ...
- Java实现 LeetCode 429 N叉树的层序遍历
429. N叉树的层序遍历 给定一个 N 叉树,返回其节点值的层序遍历. (即从左到右,逐层遍历). 例如,给定一个 3叉树 : 返回其层序遍历: [ [1], [3,2,4], [5,6] ] 说明 ...
- Java实现 蓝桥杯VIP 算法训练 数位分离
** 算法训练 数位分离** 问题描述 编写一个程序,输入一个1000 以内的正整数,然后把这个整数的每一位数字都分离出来,并逐一地显示. 输入格式:输入只有一行,即一个1000以内的正整数. 输出格 ...
- java实现第九届蓝桥杯最大乘积
最大乘积 把 1~9 这9个数字分成两组,中间插入乘号, 有的时候,它们的乘积也只包含1~9这9个数字,而且每个数字只出现1次. 比如: 984672 * 351 = 345619872 98751 ...
- 【Mysql】使用一条sql查询出库表结构信息
1.新建查询 将以下脚本粘贴进去 脚本如下: SELECT TABLE_SCHEMA 库名, TABLE_NAME 表名, COLUMN_NAME 列名, COLUMN_TYPE 数据类型, DATA ...
- Python学习之计算机基础
计算机基础: (1)计算机俗称电脑,是现代用于高速计算的电子计算器,可以进行数值计算也可以进行逻辑计算,还有存储记忆功能.是能够按照程序运行,自动,高速处理海量数据的现代化智能 电子设备. (2)物理 ...