Scrapy框架之代理和cookie
Cookie 是在 HTTP 协议下,服务器或脚本可以维护客户工作站上信息的一种方式。Cookie 是由 Web 服务器保存在用户浏览器(客户端)上的小文本文件,它可以包含有关用户的信息。无论何时用户链接到服务器,Web 站点都可以访问 Cookie 信息cookie需要个人用户登录网站。
场景需求:获取用户个人主页二级页面的页面数据。
一、Scrapy发起post请求
要登录网站,因此必须发送post请求,如何实现发送post请求?
场景需求:百度翻译中指定词条对应的翻译结果进行获取。
1、方法一:重写start_requests方法来发送post请求
爬虫文件中的爬虫类继承到了Spider父类中的start_requests(self)这个方法,该方法就可以对start_urls列表中的url发起请求。
该方法默认的实现,是对起始的url发起get请求,如果想发起post请求,则需要子类重写该方法。
import scrapy
class PostdemoSpider(scrapy.Spider):
name = 'postDemo'
# allowed_domains = ['www.baidu.com']
start_urls = ['https://fanyi.baidu.com/sug'] # 通过抓包找到post请求地址
def start_requests(self):
"""重写的父类方法:该方法可以对star_urls列表中的元素进行get请求发送"""
for url in self.start_urls:
# Request方法默认发送get请求,配置method参数赋值为'post'
yield scrapy.Request(url=url, callback=self.parse, method='post')
def parse(self, response):
pass
2、方法二:利用FormRequest方法来发送post请求(推荐)
(1)编写爬虫文件postDemo.py
import scrapy
class PostdemoSpider(scrapy.Spider):
name = 'postDemo'
# allowed_domains = ['www.baidu.com']
start_urls = ['https://fanyi.baidu.com/sug'] # 通过抓包找到post请求地址
def start_requests(self):
"""重写的父类方法:该方法可以对star_urls列表中的元素进行get请求发送"""
print("start_requests()被调用")
data = {
'kw': 'dog', # post请求参数
}
for url in self.start_urls:
# FormRequest()可以发送post请求
# formdata表示请求参数对应的字典
yield scrapy.FormRequest(url=url, formdata=data, callback=self.parse)
def parse(self, response):
print(response.text)
(2)编辑settings.py文件
# Crawl responsibly by identifying yourself (and your website) on the user-agent
USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36' # 伪装请求载体身份
# Obey robots.txt rules
ROBOTSTXT_OBEY = False # 不遵从门户网站robots协议,避免某些信息爬取不到
(3)创建项目、创建应用、执行爬虫
# 创建项目和应用(后面的项目将不再描述)
$ scrapy startproject postPro
$ cd postPro/
$ scrapy genspider postDemo www.baidu.com
# 执行爬虫命令
$ scrapy crawl postDemo --nolog
start_requests()被调用
{"errno":0,"data":[{"k":"dog","v":"n. \u72d7; \u8e69\u811a\u8d27; \u4e11\u5973\u4eba; \u5351\u9119\u5c0f\u4eba; v. \u56f0\u6270; \u8ddf\u8e2a;"},{"k":"dogs","v":"n. \u516c\u72d7( dog\u7684\u540d\u8bcd\u590d\u6570 ); \uff08\u5c24\u7528\u4e8e\u5f62\u5bb9\u8bcd\u540e\uff09\u5bb6\u4f19; [\u673a\u68b0\u5b66]\u5939\u5934; \u4e0d\u53d7\u6b22\u8fce\u7684\u4eba;"},{"k":"doge","v":"n. \u5171\u548c\u56fd\u603b\u7763;"},{"k":"doggy","v":"n. \u5c0f\u72ac\uff0c\u5c0f\u72d7; adj. \u50cf\u72d7\u4e00\u6837\u7684;"},{"k":"doggie","v":"n. \u5c0f\u72d7\uff0c\u72d7\uff0c\u6c6a\u6c6a;"}]}
二、cookie操作
知道post请求后,来实现最开始的场景需求:获取用户个人主页二级页面的页面数据。
新建项目doubanPro,这里没有在管道中处理,简化操作直接在爬虫文件中持久化数据保存在文件中,爬虫文件douban.py如下所示:
import scrapy
class DoubanSpider(scrapy.Spider):
name = 'douban'
allowed_domains = ['www.douban.com']
start_urls = ['https://www.douban.com/accounts/login']
def start_requests(self):
"""重写父类方法"""
# 将请求参数封装到字典
data = {
'source': 'index_nav',
'form_email': '18xxxxxxx0',
'form_password': 'hxxxxxxx'
}
for url in self.start_urls:
yield scrapy.FormRequest(url=url, formdata=data, callback=self.parse)
def parseBySecondPage(self, response):
"""针对个人主页页面数据进行解析操作"""
fp = open('second.html', 'w', encoding='utf-8')
fp.write(response.text)
# 可以对当前用户的个人主页数据进行指定解析操作
# 如果服务器端可以给我们的请求返回一个cookie,第二次使用请求对象发起请求时,cookie就会自动携带到请求中
def parse(self, response):
# 对登录成功后的页面数据进行存储
# 这里没有在管道中处理,简化操作直接保存在文件中
fp = open('main.html', 'w', encoding='utf-8')
fp.write(response.text)
# 获取当前用户的个人主页
url = 'https://www.douban.com/people/186757832/'
yield scrapy.Request(url=url, callback=self.parseBySecondPage)
1、重写父类方法start_requests发起post请求
def start_requests(self):
"""重写父类方法"""
# 将请求参数封装到字典
data = {
'source': 'index_nav',
'form_email': '18xxxxxx0',
'form_password': 'hxxxxxxx'
}
for url in self.start_urls:
yield scrapy.FormRequest(url=url, formdata=data, callback=self.parse)
2、parse和parseBySecondPage方法两次对个人主页发起请求
def parseBySecondPage(self, response):
"""针对个人主页页面数据进行解析操作"""
fp = open('second.html', 'w', encoding='utf-8')
fp.write(response.text)
def parse(self, response):
# 对登录成功后的页面数据进行存储
fp = open('main.html', 'w', encoding='utf-8')
fp.write(response.text)
# 获取当前用户的个人主页
url = 'https://www.douban.com/people/186757832/'
yield scrapy.Request(url=url, callback=self.parseBySecondPage)
如果服务器端可以给我们的请求返回一个cookie,第二次使用请求对象发起请求时,cookie就会自动携带到请求中。
查看mian.html和second.html文件,可以发现两次访问结果相同,说明第二次发请求时携带了cookie。
三、Scrapy代理操作
1、本地ip获取
新建proxyPro工程,通过爬虫在百度搜索ip,获取本地ip地址。
import scrapy
class ProxydemoSpider(scrapy.Spider):
name = 'proxyDemo'
# allowed_domains = ['www.baidu.com/s?wd=ip']
start_urls = ['http://www.baidu.com/s?wd=ip'] # 百度搜索到本地ip
def parse(self, response):
fp = open('proxy.html', 'w', encoding='utf-8')
fp.write(response.text)
爬虫文件编辑好后,修改settings.py文件,执行爬虫:scrapy crawl proxyDemo --nolog;查看proxy.html内容如下所示:
2、下载中间件(Downloader Middlewares)介绍
- 平常情况:
引擎调用start_requests方法,对列表中对应的列表元素进行请求,所有请求成功后,移交给引擎,引擎再将请求提交给调度器,这些请求都放置在调度器队列当中,调度给 下载器,下载器拿到对应的请求去互联网进行下载。 - 代理操作:
调度器将请求给下载器的时候,会穿过下载中间件,下载中间件就可以对请求进行拦截,更换请求对应的ip,换为其他的代理IP。代理IP更换后将请求发给下载器,下载器用修改过ip的请求去互联网去下载。 - 下载中间件的作用:
拦截调度器发给下载器的请求,将请求当中对应的IP进行更换,下载器拿到IP更换后的请求去互联网进行数据的下载。
3、代理操作代码实现
在项目当前的源文件middlewares.py中,可以看到类:ProxyproDownloadMiddleware,这是封装好的下载中间件。其中process_request方法最为重要,负责处理请求。
在全网代理IP网站:http://www.goubanjia.com/,查找一条代理IP地址(39.137.69.10:8434)使用。
(1)自定义下载中间件的类
在middlewares.py中,自定义一个下载中间件的类,在类中实现process_request方法来处理中间件拦截到的请求。
from scrapy import signals
class MyProxy(object):
# 自定义下载中间件
def process_request(self, request, spider):
# 将拦截的请求的请求ip更换
request.meta["proxy"] = "http://39.137.69.10:8434"
注意:
- 自定义类继承object类;
- 重写process_request方法,必须包含父类的self、request、spider这三个参数;
- 用request调出meta这个属性,修改meta中'proxy'这个key对应的value值更换为要修改的代理ip。
(2)修改settings.py使用自定义的中间件
使用下载中间件,需要在配置文件中开启下载中间件。
# Enable or disable downloader middlewares
# See https://doc.scrapy.org/en/latest/topics/downloader-middleware.html
DOWNLOADER_MIDDLEWARES = { # 开启下载中间件
# 'proxyPro.middlewares.ProxyproDownloaderMiddleware': 543,
# 自定义下载中间件
'proxyPro.middlewares.MyProxy': 543, # 543为优先级级别
}
(3)执行爬虫查看百度搜索得到的ip地址
$ scrapy crawl proxyDemo
查看获得的页面信息:
Scrapy框架之代理和cookie的更多相关文章
- Scrapy框架--代理和cookie
如何发起post请求? 代理和cookie: cookie:豆瓣网个人登录,获取该用户个人主页这个二级页面的页面数据. 如何发起post请求? 一定要对start_requests方法进行重写. 1. ...
- 爬虫--requests模块高级(代理和cookie操作)
代理和cookie操作 一.基于requests模块的cookie操作 引言:有些时候,我们在使用爬虫程序去爬取一些用户相关信息的数据(爬取张三“人人网”个人主页数据)时,如果使用之前requests ...
- 爬虫之代理和cookie的处理
代理操作 代理的目的 为解决ip被封的情况 什么是代理 代理服务器:fiddler 为什么使用代理可以改变请求的ip 本机的请求会先发送给代理服务器,代理服务器会接受本机发送过来的请求(当前请求对应的 ...
- Jmeter的代理和cookie/session/Token令牌认证
Jmeter的代理服务器 1.启动Jmeter: 2.“测试计划”中添加“线程组”: 3.“工作台”中添加“HTTP代理服务器”: 4.配置代理服务器:Global Settings下面的端口配置:9 ...
- 爬虫--Scrapy框架课程介绍
Scrapy框架课程介绍: 框架的简介和基础使用 持久化存储 代理和cookie 日志等级和请求传参 CrawlSpider 基于redis的分布式爬虫 一scrapy框架的简介和基础使用 a) ...
- scrapy框架使用笔记
目前网上有很多关于scrapy的文章,这里我主要介绍一下我在开发中遇到问题及一些技巧: 1,以登录状态去爬取(带cookie) -安装内容: brew install phantomjs (MAC上) ...
- 总结两种动态代理jdk代理和cglib代理
动态代理 上篇文章讲了什么是代理模式,为什么用代理模式,从静态代理过渡到动态代理. 这里再简单总结一下 什么是代理模式,给某个对象提供一个代理对象,并由代理对象控制对于原对象的访问,即客户不直接操控原 ...
- python爬虫scrapy框架——人工识别登录知乎倒立文字验证码和数字英文验证码(2)
操作环境:python3 在上一文中python爬虫scrapy框架--人工识别知乎登录知乎倒立文字验证码和数字英文验证码(1)我们已经介绍了用Requests库来登录知乎,本文如果看不懂可以先看之前 ...
- 一个scrapy框架的爬虫(爬取京东图书)
我们的这个爬虫设计来爬取京东图书(jd.com). scrapy框架相信大家比较了解了.里面有很多复杂的机制,超出本文的范围. 1.爬虫spider tips: 1.xpath的语法比较坑,但是你可以 ...
随机推荐
- Wormholes 虫洞 BZOJ 1715 spfa判断负环
John在他的农场中闲逛时发现了许多虫洞.虫洞可以看作一条十分奇特的有向边,并可以使你返回到过去的一个时刻(相对你进入虫洞之前).John的每个农场有M条小路(无向边)连接着N (从1..N标号)块地 ...
- 红蓝对抗 - 蓝队手册(BTFM)(转载)
本文已发表在嘶吼RoarTalk,未经授权,请勿转载! http://www.4hou.com/technology/10173.html 最佳阅读体验版:https://stackedit.io/v ...
- IntelliJ IDEA(Android Studio)设置代码的快捷编辑模板Live Templates
1.file---->setttings 2.editor--->live template 3.点击右侧的+ 4.设置模板 注意:Abbreviation为代码模板的缩写.
- RNA-seq分析htseq-count的使用
HTSeq作为一款可以处理高通量数据的python包,由Simon Anders, Paul Theodor Pyl, Wolfgang Huber等人携手推出HTSeq — A Python fra ...
- Moving docker images location to different partition
By default docker will put all the data including images under /var/lib/docker(At least on Debian). ...
- CF248E Piglet's Birthday(概率dp)
题面 luogu CodeForces 题解 \(orz\) yyb 转移蜜罐其实是吓唬人的...... 转移的蜜罐都是尝试过的,所有只关心当前架子上的蜜罐数 设\(f[i][j]\)表示第i个货架有 ...
- Python项目自动生成当前项目的requirements文件
使用pip freeze $ pip freeze > requirements.txt 这种方式是把整个环境中的包都列出来了,如果是虚拟环境可以使用. 通常情况下我们只需要导出当前项目的r ...
- Tensorlflow-神经网络解决非线性回归问题
import tensorflow as tfimport numpy as npimport matplotlib.pyplot as plt #使用numpy生成200个随机点,范围从-0.5到0 ...
- 补档 Codeblocks下的文件标题栏(标签)显示方法
可能在以下链接也能看到这篇文档 我知道很多人都不知道这个到底叫啥,还不如直接一点: 文件标题栏 就是如下的效果. 解决办法: 在左上角第三个view下,打开后取消Hide editor tabs 选项 ...
- 异步的模块合并管理器-m3m4版本和jquery版本(原创)
m3m4版本 (function(w){ var loading={} var models={} function define(name,args){ loading[name]=true mod ...