scrapy 知乎的模拟登陆及抓取用户数据
最近看了python的scrapy 框架并用其抓取了部分知乎用户数据,代码主要是集中在知乎登陆和抓取时候的逻辑处理上。
1、 首先进入知乎登陆页面zhihu.com/#sigin上, 用xpath提取_xsrf参数, 获取验证码的部分url,完整的url是由当前的时间戳和type参数构成,利用得到的url形成response, 在函数handle_captcha对验证码提取并提示在终端输入验证码,最后再将登陆的url、cookie、用户账号、密码什么的from进去就可以登陆成功了。下面是代码:
# _*_coding:utf-8_*_ from scrapy.spider import CrawlSpider
from scrapy.http import Request, FormRequest
from scrapy.selector import Selector
from zhihu2 import config
from PIL import Image
import time
import json
import re
from zhihu2 import items class ZhiHu_spider(CrawlSpider):
name = 'zhihu2'
allowed_domain = ['https://www.zhihu.com'] def __init__(self, *args, **kwargs):
super(ZhiHu_spider, self).__init__(*args, **kwargs)
self.xsrf = ''
self.headers = config.headers def start_requests(self):
yield Request(
'http://www.zhihu.com/#signin',
meta={
'cookiejar': 1
},
callback=self.post_login
) def post_login(self, response):
print 'parper login in '
sel = Selector(response)
self.xsrf = sel.xpath('//input[@name="_xsrf"]/@value').extract()[0] #验证码的获取 没有自动识别 识别率太低 所以手打
str_time = str(time.time() * 1000)
cap_url = 'https://www.zhihu.com/captcha.gif?r=' + str_time + '&type=login'
print cap_url
yield Request(
cap_url,
meta={'cookiejar': response.meta['cookiejar'],
'_xsrf': self.xsrf,
}, headers=self.headers,
callback=self.handle_captcha ) def handle_captcha(self, response):
with open('E:\\myscrapy\\captcha.gif', 'wb') as gif:
gif.write(response.body)
gif.close()
Im = Image.open('E:\\myscrapy\\captcha.gif')
Im.show()
captcha = raw_input('enter your captcha:') yield FormRequest(
'http://www.zhihu.com/login/phone_num', #s手机号登陆, 对应的可以换成邮箱
method='POST',
meta={'cookiejar': response.meta['cookiejar']},
headers=self.headers,
formdata={
'_xsrf': self.xsrf,
'password': '密码',
'remember_me': 'true',
'phone_num': '账号',
'captcha': captcha
},
callback=self.after_login, )
2、下面是登陆之后获取关注人的信息,由于知乎第一次只会显示20个关注人,剩下的要post数据到www.zhihu.com/node/ProfileFolloweesList2
才能又获取20个,所以在这要获取每个人的关注人数并与20做对比。
# 获取个人主页
def after_login(self, response):
print response.body
print 'login success'
yield Request(
'https://www.zhihu.com/people/你的id需要填写, #自己主页的网址 因为我没获取id 所以要输入自己主页的网址
meta={'cookiejar': response.meta['cookiejar']},
headers=self.headers,
callback=self.parse_people,
)
#获取关注人url
def parse_people(self, response):
# print 'ready'
sel = Selector(response)
follow_url = sel.xpath('//a[@class="item"]/@href').extract_first()
if follow_url:
compete_url = 'https://www.zhihu.com' + follow_url yield Request(
compete_url,
meta={
'cookiejar': response.meta['cookiejar'],
},
headers=self.headers,
callback=self.person_info,
) #处理关注人的url 并获取信息
def person_info(self, response):
item = items.Zhihu2Item()
count = 20
sel = Selector(response) nikname = sel.xpath('//div[@class="title-section"]/a[@class="name"]/text()').extract_first()
location = sel.xpath('//span[@class="location item"]/@title').extract_first()
business = sel.xpath('//span[@class="business item"]/@title').extract_first()
education = sel.xpath('//span[@class="education item"]/@title').extract_first()
education_extra = sel.xpath('//span[@class="education-extra item"]/@title').extract_first()
sex = sel.xpath('//span[@class="item gender"]/i/@class').extract_first().split('-')[-1]
agree = sel.xpath('//span[@class="zm-profile-header-user-agree"]/strong/text()').extract_first()
thanks = sel.xpath('//span[@class="zm-profile-header-user-thanks"]/strong/text()').extract_first() config.try_none(nikname)
config.try_none(location)
config.try_none(business)
config.try_none(education)
config.try_none(education_extra)
config.try_none(sex)
config.try_none(agree)
config.try_none(thanks) peo_num = sel.xpath('/html/body/div[3]/div[2]/div[1]/a[1]/strong/text()').extract_first()
item['nikname'] = nikname
item['business'] = business
item['education_extra'] = education_extra
item['location'] = location
item['education'] =education
item['sex'] = sex
item['agree'] = agree
item['thanks'] = thanks if peo_num: people_urls = sel.xpath('//a[@class="zg-link author-link"]/@href').extract()
for people_url in people_urls:
yield Request(
people_url,
meta={'cookiejar': response.meta['cookiejar']},
headers=self.headers,
callback=self.person_info
) peo_params = sel.xpath('//div[@class="zh-general-list clearfix"]/@data-init').extract_first()
if peo_params:
try:
values = json.loads(str(peo_params))
except ValueError, e:
print e.message
params = {}
params['offset'] = 20
params['order_by'] = 'created'
params['hash_id'] = values['params']['hash_id'] if count < peo_num:
params['offset'] = count
yield FormRequest(
'https://www.zhihu.com/node/ProfileFolloweesListV2',
method='POST',
meta={'cookiejar': response.meta['cookiejar']},
headers=self.headers,
formdata={
'method': 'next',
'params': json.dumps(params),
'_xsrf': self.xsrf,
},
callback=self.foolows_V2
)
count += 20
else:
num = peo_num / 20
params['offset'] = num
yield FormRequest(
'https://www.zhihu.com/node/ProfileFolloweesListV2',
method='POST',
meta={'cookiejar': response.meta['cookiejar']},
headers=self.headers,
formdata={
'method': 'next',
'params': json.dumps(params),
'_xsrf': self.xsrf,
},
callback=self.foolows_V2
)
3、从上面url的response获取关注人的url,得到的url 交由parse_people函数处理,parse_people函数的response交由person_info函数处理,所以就形成了一个循环,不断的有url被提取,也不断的有数据被提取出来,下面是parse_people函数的代码:
def foolows_V2(self, response):
p = re.compile(r'href="https://www\.zhihu\.com/people/(.*?)"') aa = json.loads(response.body)['msg']
for item in aa:
peo = p.search(item).group(1)
followes_url = 'https://www.zhihu.com/people/' + str(peo)
yield Request(
followes_url,
meta={'cookiejar': response.meta['cookiejar']},
headers=self.headers,
callback=self.parse_people
)
下面是一些配置信息:
cofig.py
#_*_coding:utf-8_*_
from settings import USER_AGENT
headers = {
'Host': 'www.zhihu.com',
'Connection': 'keep-alive',
'Pragma': 'no-cache',
'Cache-Control': 'no-cache',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Origin': 'https://www.zhihu.com',
'X-Requested-With': 'XMLHttpRequest',
'User-Agent': USER_AGENT,
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'Referer': 'https://www.zhihu.com/',
'Accept-Encoding': 'gzip,deflate,sdch',
'Accept-Language': 'zh-CN,zh;q=0.8',
}
def try_none(tag):
try:
tag
except:
tag = 'none'
return tag
items.py:
from scrapy import Item, Field class Zhihu2Item(Item):
nikname = Field()
location = Field()
business = Field()
education = Field()
education_extra = Field()
sex = Field()
thanks = Field()
agree = Field()
代码没有维护已爬取的url和带爬取的url的重复,可能会导致重复抓取,代码的优化也挺烂的。希望大神们多给点意见,如果代码有错误,希望提出,以免给别人误导。
scrapy 知乎的模拟登陆及抓取用户数据的更多相关文章
- 【转】详解抓取网站,模拟登陆,抓取动态网页的原理和实现(Python,C#等)
转自:http://www.crifan.com/files/doc/docbook/web_scrape_emulate_login/release/html/web_scrape_emulate_ ...
- Scrapy模拟登陆豆瓣抓取数据
scrapy startproject douban 其中douban是我们的项目名称 2创建爬虫文件 进入到douban 然后创建爬虫文件 scrapy genspider dou douban. ...
- 爬虫模拟登陆之formdata表单数据
首先HTTP协议是个无连接的协议,浏览器和服务器之间是以循环往复的请求回复来交互的,交互的形式是以文件形式来进行的.比如在chrome开发者工具network中看到了 每一行是一个文件,又文件大小啊, ...
- Android(Java) 模拟登录知乎并抓取用户信息
前不久.看到一篇文章我用爬虫一天时间"偷了"知乎一百万用户.仅仅为证明PHP是世界上最好的语言,该文章中使用的登录方式是直接复制cookie到代码中,这里呢,我不以爬信息为目的.仅 ...
- Java模拟登陆新浪微博抓取数据【转载】
package com.shiyimm.crawler.weibo; import java.io.FileNotFoundException; import java.io.FileReader; ...
- Scrapy 模拟登陆知乎--抓取热点话题
工具准备 在开始之前,请确保 scrpay 正确安装,手头有一款简洁而强大的浏览器, 若是你有使用 postman 那就更好了. Python 1 scrapy genspid ...
- Scrapy 中的模拟登陆
目前,大部分网站都具有用户登陆功能,其中某些网站只有在用户登陆后才能获得有价值的信息,在爬取这类网站时,Scrapy 爬虫程序先模拟登陆,再爬取内容 1.登陆实质 其核心是想服务器发送含有登陆表单数据 ...
- 【教程】手把手教你如何利用工具(IE9的F12)去分析模拟登陆网站(百度首页)的内部逻辑过程
[前提] 想要实现使用某种语言,比如Python,C#等,去实现模拟登陆网站的话,首先要做的事情就是使用某种工具,去分析本身使用浏览器去登陆网页的时候,其内部的执行过程,内部逻辑. 此登陆的逻辑过程, ...
- 使用C#的HttpWebRequest模拟登陆访问人人网
使用任何语言做模拟登陆或者抓取访问页面,无外乎以下思路: 第一 启用一个web访问会话方法或者实例化一个web访问类,如.net中的HttpWebRequest:第二 模拟POST或者GET方式提交的 ...
随机推荐
- 【Spring】基于注解的实现SpringMVC+MySQL
目录结构: // contents structure [-] SprinigMVC是什么 SpringMVC工作原理 @Controller和@RequestMapping注解 @Controlle ...
- 【C#】Deep copy of objects
If you learned C++ carefully, you must have known something about the copy of object. For example, I ...
- 使用Redis的Java客户端Jedis
转载自:http://aofengblog.blog.163.com/blog/static/631702120147298317919/ 前一篇文章<Redis命令指南>讲解了通过命令行 ...
- 前端——HTML笔记Two
web前端需要掌握:HTML.CSS.JavaScript语言.这三门技术用来实现: 1. HTML是网页内容的载体.内容就是网页制作者放在页面上想要让用户浏览的信息,可以包含文字.图片.视频等. 2 ...
- google的作恶与不作恶
Google刚刚出现时,那时互联网还似桃花源,路不拾遗夜不闭户,最多升级升级病毒库.Google的发展,从商业模式上带来了广告对互联网无孔不入的渗透,如今Google.百度.阿里等各大巨头都有自己的广 ...
- sql数据导出导入格式化
SHELL脚本导入导出数据时,按逗号分隔,引号包含字段,null值'' gccli -uroot -h$ip -e"rmt:${sqlStr} into outfile '${name}${ ...
- Dubbo服务的搭建与使用
官方地址Dubbo.io Dubbo 主要功能 高并发的负载均衡,多系统的兼容合并(理解不深,不瞎掰了) Dubbo 主要组成有四部分 Zookeeper(服务注册中心) Consumer(服务消费方 ...
- 6.MyBaits的分页和缓存查询
1. 创建javaweb项目MyBaits_Page_CaChe 2.在项目的WebRoot下的WEB-INF下的lib文件下加入jar文件 log4j-1.2.17.jar mybatis-3.2. ...
- 怎么 得到 DBGrid选中行的数据
转自:https://zhidao.baidu.com/question/1694035814426308148.html 一般是你鼠标点到哪一行,其DataSet的指针就指到了什么位置你可以直接通过 ...
- 一篇顺手的Ubuntu+caffe配置笔记
主要参考: https://github.com/lbzhang/dl-setup http://ouxinyu.github.io/Blogs/20151108001.html http://www ...