首先,祝大家开工大吉!

本篇将要介绍的是从一个用户开始,通过抓关注列表和粉丝列表,实现用户的详细信息抓取并将抓取到的结果存储到 MongoDB。

1 环境需求

基础环境沿用之前的环境,只是增加了MongoDB(非关系型数据库)和PyMongo(Python 的 MongoDB 连接库),默认我认为大家都已经安装好并启动 了MongoDB 服务。

项目创建、爬虫创建、禁用ROBOTSTXT_OBEY设置略(可以参考上一篇)

2 测试爬虫效果

我这里先写一个简单的爬虫,爬取用户的关注人数和粉丝数,代码如下:

# -*- coding: utf-8 -*-

import scrapy

class ZhuHuSpider(scrapy.Spider):

"""

知乎爬虫

"""

name = 'zhuhu'

allowed_domains = ['zhihu.com']

start_urls = ['https://www.zhihu.com/people/wo-he-shui-jiu-xing/following']

def parse(self, response):

# 他关注的人数

tnum = response.css("strong.NumberBoard-itemValue::text").extract()[0]

# 粉丝数

fnum = response.css("strong.NumberBoard-itemValue::text").extract()[1]

print("他关注的人数为:%s" % tnum)

print("他粉丝的人数为:%s" % fnum)

pychram中运行的结果如下:

出现500错误了,我们加上headers再试试,我们直接在settings.py中设置,如下:

再次执行看看结果:

这次就正常获取到我们需要的信息了

3 爬取分析

这里要注意我用的是火狐浏览器,选择网络--XHR来获取信息

ajax技术的核心是XMLHttpRequest对象(简称XHR),这是由微软首先引入的一个特性,其他浏览器提供商后来都提供了相同的实现。XHR为向服务器发送请求和解析服务器响应提供了流畅的接口,能够以异步方式从服务器取得更多信息,意味着用户单击后,可以不必刷新页面也能取得新数据。

通过上面的请求我们可以获取的连接如下:

#用户详细信息

https://www.zhihu.com/api/v4/members/li-kang-65?include=allow_message,is_followed,is_following,is_org,is_blocking,employments,answer_count,follower_count,articles_count,gender,badge[?(type=best_answerer)].topics

https://www.zhihu.com/api/v4/members/jin-xiao-94-7?include=allow_message,is_followed,is_following,is_org,is_blocking,employments,answer_count,follower_count,articles_count,gender,badge[?(type=best_answerer)].topics

#关注的人信息

https://www.zhihu.com/api/v4/members/satoshi_nakamoto/followees?include=data[*].answer_count,articles_count,gender,follower_count,is_followed,is_following,badge[?(type=best_answerer)].topics&offset=0&limit=20

通过分析上面的链接可以看出

1.用户详细信息链接组成:https://www.zhihu.com/api/v4/members/{user}?include={include}

其中user是用户的url_token,include是allow_message,is_followed,is_following,is_org,is_blocking,employments,answer_count,follower_count,articles_count,gender,badge[?(type=best_answerer)].topics

2.关注人信息链接组成:https://www.zhihu.com/api/v4/members/satoshi_nakamoto/followees?include={include}&offset={offset}&limit={limit}

其中include为data[*].answer_count,articles_count,gender,follower_count,is_followed,is_following,badge[?(type=best_answerer)].topics,offset为分页偏移量,limit为每页用户数量,可以通过下图看出:

第一页

第二页

第三页

4 开始爬取

我们还是先写一个简易的爬虫,把功能先实现,代码如下:

# -*- coding: utf-8 -*-

import scrapy

class ZhuHuSpider(scrapy.Spider):

"""

知乎爬虫

"""

name = 'zhuhu'

allowed_domains = ['zhihu.com']

# 用户详细信息地址

user_detail = 'https://www.zhihu.com/api/v4/members/{user}?include={include}'

# 用户详细信息中的include

user_include = 'allow_message,is_followed,' \

'is_following,' \

'is_org,is_blocking,' \

'employments,' \

'answer_count,' \

'follower_count,' \

'articles_count,' \

'gender,' \

'badge[?(type=best_answerer)].topics'

# 关注的人地址

follow_url = 'https://www.zhihu.com/api/v4/members/{user}/followees?include={include}&offset={offset}&limit={limit}'

# 关注的人include

follow_include = 'data[*].answer_count,' \

'articles_count,' \

'gender,' \

'follower_count,' \

'is_followed,' \

'is_following,' \

'badge[?(type=best_answerer)].topics'

# 初始user

start_user = 'satoshi_nakamoto'

def start_requests(self):

# 这里重新定义start_requests方法,注意这里的format用法

yield scrapy.Request(self.user_detail.format(user=self.start_user, include=self.user_include),

callback=self.parse_user)

yield scrapy.Request(self.follow_url.format(user=self.start_user, include=self.follow_include, offset=20, limit=20),

callback=self.parse_follow)

def parse_user(self, response):

print('user:%s' % response.text)

def parse_follow(self, response):

print('follow:%s' % response.text)

输出结果如下:

这里需要注意的是authorization信息一定要在headers中添加,不然会报错,authorization在headers中的形式如下:

测试发现authorization值在一段时间内是不会发生变化的,是否永久不变还有待考证。

5 parse_user编写

parse_user方法用来解析用户的详细数据,存储并发现此用户的关注列表,返回给parse_follow方法来处理,用户详细存储字段如下:

为了省事我把所有字段都添加到items.py中(如果运行spider后报错,提示字段未找到,就将那个字段添加进来即可),如下:

class UserItem(scrapy.Item):

"""

定义了响应报文中json的字段

"""

is_followed = scrapy.Field()

avatar_url_template = scrapy.Field()

user_type = scrapy.Field()

answer_count = scrapy.Field()

is_following = scrapy.Field()

url = scrapy.Field()

type = scrapy.Field()

url_token = scrapy.Field()

id = scrapy.Field()

allow_message = scrapy.Field()

articles_count = scrapy.Field()

is_blocking = scrapy.Field()

name = scrapy.Field()

headline = scrapy.Field()

gender = scrapy.Field()

avatar_url = scrapy.Field()

follower_count = scrapy.Field()

is_org = scrapy.Field()

employments = scrapy.Field()

badge = scrapy.Field()

is_advertiser = scrapy.Field()

parse_user方法代码如下:

def parse_user(self, response):

"""

解析用户详细信息方法

:param response: 获取的内容,转化为json格式

"""

# 通过json.loads方式转换为json格式

results = json.loads(response.text)

# 引入item类

item = UserItem()

# 通过循环判断字段是否存在,存在将结果存入items中

for field in item.fields:

if field in results.keys():

item[field] = results.get(field)

# 直接返回item

yield item

# 将获取的用户通过format方式组合成新的url,调用callback函数交给parse_follow方法解析

yield scrapy.Request(self.follows_url.format(user=results.get('url_token'),

include=self.follow_include, offset=0, limit=20),

callback=self.parse_follow)

6 parse_follow方法编写

首先也要将获取的response转换为json格式,获取关注的用户,对每一个用户继续爬取,同时也要处理分页。可以看下面两个图:

重新编写后的parse_follow方法如下:

def parse_follow(self, response):

"""

解析关注的人列表方法

"""

# 格式化response

results = json.loads(response.text)

# 判断data是否存在,如果存在就继续调用parse_user解析用户详细信息

if 'data' in results.keys():

for result in results.get('data'):

yield scrapy.Request(self.user_detail.format(user=result.get('url_token'), include=self.user_include),

callback=self.parse_user)

# 判断paging是否存在,如果存在并且is_end参数为False,则继续爬取下一页,如果is_end为True,说明为最后一页

if 'paging' in results.keys() and results.get('paging').get('is_end') == False:

next_page = results.get('paging').get('next')

yield scrapy.Request(next_page, callback=self.parse_follow)

运行爬虫后的结果如下图:

可以看到一直在获取内容。

7 存入mongodb

7.1 item pipeline

存储使用MongoDB,我们需要修改Item Pipeline,参照官网示例修改的代码如下:

class ZhiHuspiderPipeline(object):

"""

知乎数据存入monogodb数据库类,参考官网示例

"""

collection_name = 'user'

def __init__(self, mongo_uri, mongo_db):

"""

初始化参数

:param mongo_uri:mongo uri

:param mongo_db: db name

"""

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_DATABASE', 'items')

)

def open_spider(self, spider):

# 打开连接

self.client = pymongo.MongoClient(self.mongo_uri)

# db_auth因为我的mongodb设置了认证,所以需要这两步,未设置可以注释

self.db_auth = self.client.admin

self.db_auth.authenticate("admin", "password")

self.db = self.client[self.mongo_db]

def close_spider(self, spider):

self.client.close()

def process_item(self, item, spider):

# 这里使用update方法

self.db[self.collection_name].update({'url_token': item['url_token']}, dict(item), True)

return item

这里要说一说update方法,update() 方法用于更新已存在的文档。语法格式如下:

db.collection.update(

, # update的查询条件,类似sql update查询内where后面的

, # update的对象和一些更新的操作符(如$,$inc...)等,也可以理解为sql update查询内set后面的

{

upsert: , # 可选,这个参数的意思是,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。

multi: , # 可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新

writeConcern: # 可选,抛出异常的级别。

}

)

使用update方法,如果查询数据存在的话就更新,不存在的话就插入dict(item),这样就可以去重了。

7.2 settings配置

再次运行spider后结果如下:

也可以看到mongodb中数据,如下:

到此本篇完结。

yield python3 知乎_运维学python之爬虫高级篇(七)scrapy爬取知乎关注用户存入mongodb...相关推荐

  1. 运维学python之爬虫工具篇(四)PhantomJS的用法

    1 介绍 PhantomJS是一个×××面的,可脚本编程的WebKit浏览器引擎.它原生支持多种web 标准:DOM 操作,CSS选择器,JSON,Canvas 以及SVG.官方文档 2 安装 Pha ...

  2. python urllib.request 爬虫 数据处理-运维学python之爬虫基础篇(二)urllib模块使用...

    1 何为爬虫 网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本.另外一些不常使用的名字还有蚂蚁.自动索引. ...

  3. 运维学python哪部分_初入运维的小伙伴,别再问需不需要学Python了

    这篇文章来自百度知道(你可以搜索"运维需不需要学Python"),或许有些观点不一定正确,但运维学Python这事毫无疑问是主流了,不信可以到各大招聘网站,看看但凡招聘运维有编程技 ...

  4. Scrapy爬取知乎Python专题精华,连答主头像都给爬下来,不放过一切

    前些天写的一篇"我与Scrapy的初次相识,理论+实战入门Scrapy "都上首页推荐了,到现在浏览量还没破百,难受. 写的不好大概,不过只要有一人看,都是鼓励,一直写,一直积淀, ...

  5. python爬虫实战(一)--爬取知乎话题图片

    原文链接python爬虫实战(一)–爬取知乎话题图片 前言 在学习了python基础之后,该尝试用python做一些有趣的事情了–爬虫. 知识准备: 1.python基础知识 2.urllib库使用 ...

  6. Scrapy爬取知乎用户信息以及人际拓扑关系

    Scrapy爬取知乎用户信息以及人际拓扑关系 1.生成项目 scrapy提供一个工具来生成项目,生成的项目中预置了一些文件,用户需要在这些文件中添加自己的代码. 打开命令行,执行:scrapy sta ...

  7. Python3网络爬虫开发实战,Scrapy 爬取新浪微博

    前面讲解了 Scrapy 中各个模块基本使用方法以及代理池.Cookies 池.接下来我们以一个反爬比较强的网站新浪微博为例,来实现一下 Scrapy 的大规模爬取. 很多人学习python,不知道从 ...

  8. Scrapy爬取知乎用户信息

    1 爬取逻辑 先选取一个用户,爬取他的粉丝列表和关注列表.然后对每个粉丝进行分析,找出他们的粉丝列表和关注列表,以此往复,递归下去,就可以爬取大部分的用户信息了.通过一个树形的结构,蔓延到所有的用户. ...

  9. 使用python scrapy爬取知乎提问信息

    前文介绍了python的scrapy爬虫框架和登录知乎的方法. 这里介绍如何爬取知乎的问题信息,并保存到mysql数据库中. 首先,看一下我要爬取哪些内容: 如下图所示,我要爬取一个问题的6个信息: ...

最新文章

  1. Maven最全笔记,99%的人都收藏了!
  2. db2 如何导出insert语句_《MySQL 入门教程》第 23 篇 DML 语句之插入数据
  3. 推荐:机器学习实战项目练手的平台
  4. php parseint,JavaScript parseInt() 函数
  5. c++数据结构与算法 图
  6. seL4操作系统基础06:dataport interface与seL4SharedData connector
  7. 软件设计师21-计算机体系结构
  8. cocos2dx游戏开发简单入门视频教程 (cocos2d-x)- 第5天
  9. 谷歌修复又一枚遭在野利用的 Chrome 0day
  10. 最通俗易懂的命名实体识别NER模型中的CRF层介绍
  11. nodejs的简单爬虫
  12. android tv背景图片,android中shape绘制背景图片
  13. socket 源码分析
  14. CronTrigger(重要,非常强大)
  15. 数字逻辑课程设计(一):数字时钟——logisam模拟实现
  16. uva 10247 - Complete Tree Labeling(dp)
  17. QT软件开发: 基于FFMPGE设计的流媒体播放器(rtmp/rtsp)
  18. 服务器安装系统提示加载驱动程序,解决安装win7的提示“加载驱动程序”的问题...
  19. printf二进制输出
  20. 2022全网最全的持续集成基础【你知道的和不知道都在这里】

热门文章

  1. python图像变形
  2. 第 1 章 虚拟化 - 013 - 动手实践 Linux VLAN
  3. 清北学堂培训2019.4.7
  4. python3-泊松分布
  5. Android 性能优化
  6. cmake 常用变量和常用环境变量查表手册
  7. ViewPager+RadioGroup实现标题栏切换,Fragment切换
  8. jQurey 的选择器
  9. SQL Server的一个不显眼的功能 备份文件的分割
  10. Ubuntu14.04安装JDK