使用python scrapy爬取知乎提问信息
前文介绍了python的scrapy爬虫框架和登录知乎的方法.
这里介绍如何爬取知乎的问题信息,并保存到mysql数据库中.
首先,看一下我要爬取哪些内容:
如下图所示,我要爬取一个问题的6个信息:
- 问题的id(question_id)
- 标题(title)
- 问题描述(intro)
- 回答个数(answer_num)
- 关注人数(attention_uv)
- 浏览次数(read_pv)

爬取结果我保存到mysql数据库中,表名为:zhihu_question
如下图中,红框里的就是上图是有人为我的穿着很轻浮,我该如何回应?问题的信息.
(回答个数,关注着和浏览次数数据不一致是因为我是在爬取文章信息之后的一段时间才抽出来时间写的文章,在这期间回答个数,关注着和浏览次数都会增长.)

爬取方法介绍
我用的是scrapy框架中自带的选择器selectors.
selectors通过特定的 XPath 或者 CSS 表达式来“选择” HTML文件中的某个部分。
XPath 是一门用来在XML文件中选择节点的语言,也可以用在HTML上。 CSS 是一门将HTML文档样式化的语言。
XPath最最直观的介绍:
例如:知乎问题页面上的标题的XPath如下:
图中红框里就是标题的XPath.(这只是一个直观的介绍,还有一些细节可以在代码中看到)

爬取代码:
爬取问题的相关信息只需要问题url即可,我这里把收集的问题url写到文件中,爬虫程序去遍历文件,然后依次爬取.
我是在登录成功知乎后的check_login这个方法里面构造的起始url,所以读文件的方法也在这里,代码如下:
def check_login(self, response):
# 验证登录成功之后构造初始问题url
file = open("/root/py_project/zhihu/zhihu/conf/start_questions.txt")
while 1:
line = file.readline()
line = line.strip('\n') #去掉最后的换行
if not line:
break
if(line[0:1] == "#"):
#如果是#开头的url, 跳过
print line
pass
else:
print("current url : " + line)
yield scrapy.Request(line,callback=self.parse_question, headers=self.headers)
file.close()
其中最重要的一行是:
yield scrapy.Request(line,callback=self.parse_question, headers=self.headers)
yield scrapy.Request 代表开始爬取一条url,如果有多个url就yield多次. 这里的次数等同于start_question.txt中非#开头的url
如下:

callback=self.parse_question 是请求url地址后,返回的response的回调处理函数,也是整个爬取过程中最核心的代码.
如下:
def parse_question(self,response):
item = QuestionItem()
url = response.url
questionid=url[url.rindex("/")+1:]
item['questionid']=questionid
item['title']=response.selector.xpath('//*[@class="QuestionHeader-title"]/text()')[0].extract()
descarr=response.selector.xpath('//span[@itemprop="text"]/text()')
if len(descarr) > 0:
item['desc']=descarr[0].extract()
else:
item['desc']="-"
item['answer_num']=response.selector.xpath('//*[@id="QuestionAnswers-answers"]/div/div/div[1]/h4/span/text()[1]')[0].extract().replace(',','')
item['attention_uv']=response.selector.xpath('//strong[@class="NumberBoard-itemValue"]/text()')[0].extract().replace(',','')
item['read_pv']=response.selector.xpath('//strong[@class="NumberBoard-itemValue"]/text()')[1].extract().replace(',','')
yield item
其中主要代码是用selectors.xpath选取我们需要的问题信息(注意:这里的路径并不一定与 chrome的debug模式中复制的xpath一致,直接复制的xpath一般不太能用,自己看html代码结构写的),
获取到问题的信息之后放到item.py中定义好的QuestionItem对象中,然后yield 对象 , 会把对象传递到配置的pipelines中.
pipelines一般是在配置文件中配置,
因为这里爬取问题只保存到mysql数据库,并不下载图片,(而爬取答案需要下载图片)所以各自在在爬虫程序中定义的pipelines,如下:
custom_settings = {
'ITEM_PIPELINES' : {
'zhihu.mysqlpipelines.MysqlPipeline': 5
#'scrapy.pipelines.images.ImagesPipeline': 1,#这个是scrapy自带的图片下载pipelines
}
}
以上是爬取知乎问题的整个大致过程.
后文介绍爬取收藏夹下的回答 和 问题下的回答(包括内容和图片).
使用python scrapy爬取知乎提问信息的更多相关文章
- python scrapy爬取知乎问题和收藏夹下所有答案的内容和图片
上文介绍了爬取知乎问题信息的整个过程,这里介绍下爬取问题下所有答案的内容和图片,大致过程相同,部分核心代码不同. 爬取一个问题的所有内容流程大致如下: 一个问题url 请求url,获取问题下的答案个数 ...
- 利用 Scrapy 爬取知乎用户信息
思路:通过获取知乎某个大V的关注列表和被关注列表,查看该大V和其关注用户和被关注用户的详细信息,然后通过层层递归调用,实现获取关注用户和被关注用户的关注列表和被关注列表,最终实现获取大量用户信息. 一 ...
- 爬虫(十六):scrapy爬取知乎用户信息
一:爬取思路 首先我们应该找到一个账号,这个账号被关注的人和关注的人都相对比较多的,就是下图中金字塔顶端的人,然后通过爬取这个账号的信息后,再爬取他关注的人和被关注的人的账号信息,然后爬取被关注人的账 ...
- 爬虫实战--利用Scrapy爬取知乎用户信息
思路: 主要逻辑图:
- 一个简单的python爬虫,爬取知乎
一个简单的python爬虫,爬取知乎 主要实现 爬取一个收藏夹 里 所有问题答案下的 图片 文字信息暂未收录,可自行实现,比图片更简单 具体代码里有详细注释,请自行阅读 项目源码: # -*- cod ...
- scrapy 爬取知乎问题、答案 ,并异步写入数据库(mysql)
python版本 python2.7 爬取知乎流程: 一 .分析 在访问知乎首页的时候(https://www.zhihu.com),在没有登录的情况下,会进行重定向到(https://www. ...
- scrapy爬取知乎某个问题下的所有图片
前言: 1.仅仅是想下载图片,别人上传的图片也是没有版权的,下载来可以自己欣赏做手机背景但不商用 2.由于爬虫周期的问题,这个代码写于2019.02.13 1.关于知乎爬虫 网上能访问到的理论上都能爬 ...
- python scrapy爬取HBS 汉堡南美航运公司柜号信息
下面分享个scrapy的例子 利用scrapy爬取HBS 船公司柜号信息 1.前期准备 查询提单号下的柜号有哪些,主要是在下面的网站上,输入提单号,然后点击查询 https://www.hamburg ...
- Python——Scrapy爬取链家网站所有房源信息
用scrapy爬取链家全国以上房源分类的信息: 路径: items.py # -*- coding: utf-8 -*- # Define here the models for your scrap ...
随机推荐
- Docker 数据卷和数据卷容器
1.本节课主要讲解如何在Docker内部及容器之间管理数据.容器中管理数据主要有两种方式:数据卷(Data volumes)数据卷容器(Data volume containers) 2.数据卷:是一 ...
- go import使用及. _的作用解析
go中import用于导入包.导入之后就可以使用包中的代码. 比如: import( "fmt" ) 在代码中就可以使用fmt包中的方法,如: fmt.Println(" ...
- php实现猴子选大王
function getKing($n,$m) { $arr = range(1,$n); $i = 0; while(count($arr) > 1) { if(($i+1) % $m == ...
- 朴素贝叶斯分类器及Python实现
贝叶斯定理 贝叶斯定理是通过对观测值概率分布的主观判断(即先验概率)进行修正的定理,在概率论中具有重要地位. 先验概率分布(边缘概率)是指基于主观判断而非样本分布的概率分布,后验概率(条件概率)是根据 ...
- Java文件编译出现 “编码 GBK 的不可映射字符”
俗话说,温故而知新.本打算用dos回忆一下基础知识,没想到把自己绊倒了. 用Dos,当然就要回归原始,用记事本啦.下面用一个小练习,演示我遇到的绊脚石.之后,解决了简直笑死. 报错: Java文件编译 ...
- SQLite 的 CodeFirst 模式
目录 问题描述 解决方案 安装依赖包 修改程序配置 App.config 创建模型对象 Person.cs 创建数据上下文 PersonDbContext.cs 主程序调用 Program.cs 注意 ...
- 使用js从element的matrix推导transform的scale、rotate 和 translate参数
transform 网上很多都只介绍了还原角度和缩放的参数,但是没有就偏移量的计算,自己还原了一下公式的意义,进行了公式的反推,具体的推到过程就不详叙了,可以参看w3c的矩阵含义. 直接上干货. fu ...
- 【读书笔记】iOS-优化iOS Web应用
一,代码优化: 代码优化是任何优化技术的第一步,因为归根结底网页上的一切都是构建在代码之上的.优秀的代码可以节省宽带,减少渲染延迟,以及提高页面的可读性和长远的可维护性.下面列出了一些在Web应用中编 ...
- React 入门学习笔记整理(三)—— 组件
1.定义组件 1)函数组件 function GreateH(props){ return <div> <h2>hello,{props.name}</h2> &l ...
- Flume初入门简单配置与使用
1.Flume在集群中扮演的角色 Flume.Kafka用来实时进行数据收集,Spark.Storm用来实时处理数据,impala用来实时查询. 2.Flume框架简介 1.1 Flume提供一个分布 ...