本帖最后由 shenzhenwan10 于 2016-6-17 07:52 编辑

1,引言

在前一篇Scrapy:python3下的第一次运行测试 中,我们以官网的tutorial为例,成功的运行了Scrapy。

实际使用中,需要对Scrapy的各部分有更深入的了解,才能根据应用场景来灵活的添加自定义代码。

本篇就来研读一下Scrapy有关Request/Response的部分。

2,研读过程

2.1 结合官方文档例子,先简单整理出一段代码:

import scrapy

from myproject.items import MyItem

class MySpider(scrapy.Spider):

name = 'myspider'

start_urls = (

'http://example.com/page1',

'http://example.com/page2',

)

def parse(self, response):

# collect `item_urls`

for item_url in item_urls:

yield scrapy.Request(item_url, self.parse_item)

def parse_item(self, response):

item = MyItem()

# populate `item` fields

# and extract item_details_url

yield scrapy.Request(item_details_url, self.parse_details, meta={'item': item})

def parse_details(self, response):

item = response.meta['item']

# populate more `item` fields

return item复制代码说明:

从Spider继承了一个爬虫类,唯一名称 name="myspider", 爬虫默认入口地址 start_urls = () ,元组或列表都可以。

2.2 查看Scrapy有关Spider的源码,可以看到

# 代码片段

class Spider(object_ref):

"""Base class for scrapy spiders. All spiders must inherit from this

class.

"""

name = None

def __init__(self, name=None, **kwargs):

if name is not None:

self.name = name

elif not getattr(self, 'name', None):

raise ValueError("%s must have a name" % type(self).__name__)

self.__dict__.update(kwargs)

if not hasattr(self, 'start_urls'):

self.start_urls = []复制代码说明:

在Spider初始化时,检查name是否为None,start_urls 是否存在。代码很简单

2.3 继续向下看:

# 第一个方法

def parse(self, response):

# collect `item_urls`

# 可以理解为:网站的所有导航菜单的超链接集合

for item_url in item_urls:

yield scrapy.Request(item_url, self.parse_item)复制代码说明:

a) parse为默认入口,也就是从父类Spider类中继承过来的(或者说是一个必须要实现的接口),但是需要实现。

b) 在这个方法体中,根据 start_requests (默认为GET请求)返回的 Response,得到了一个 名字为‘item_urls’ 的url集合。然后遍历并请求这些集合。

2.5 再看 Request 源码:

# 部分代码

class Request(object_ref):

def __init__(self, url, callback=None, method='GET', headers=None, body=None,

cookies=None, meta=None, encoding='utf-8', priority=0,

dont_filter=False, errback=None):

self._encoding = encoding  # this one has to be set first

self.method = str(method).upper()

self._set_url(url)

self._set_body(body)

assert isinstance(priority, int), "Request priority not an integer: %r" % priority

self.priority = priority

assert callback or not errback, "Cannot use errback without a callback"

self.callback = callback

self.errback = errback

self.cookies = cookies or {}

self.headers = Headers(headers or {}, encoding=encoding)

self.dont_filter = dont_filter

self._meta = dict(meta) if meta else None

@property

def meta(self):

if self._meta is None:

self._meta = {}

return self._meta复制代码其中,比较常用的参数:

url: 就是需要请求,并进行下一步处理的url

callback: 指定该请求返回的Response,由那个函数来处理。

method: 一般不需要指定,使用默认GET方法请求即可

headers: 请求时,包含的头文件。一般不需要。内容一般如下:使用 urllib 自己写过爬虫的肯定知道

Host: media.readthedocs.org

User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64; rv:33.0) Gecko/20100101 Firefox/33.0

Accept: text/css,*/*;q=0.1

Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3

Accept-Encoding: gzip, deflate

Referer: http://scrapy-chs.readthedocs.org/zh_CN/0.24/

Cookie: _ga=GA1.2.1612165614.1415584110;

Connection: keep-alive

If-Modified-Since: Mon, 25 Aug 2014 21:59:35 GMT

Cache-Control: max-age=0

meta: 比较常用,在不同的请求之间传递数据使用的。字典dict型

request_with_cookies = Request(url="http://www.example.com",

cookies={'currency': 'USD', 'country': 'UY'},

meta={'dont_merge_cookies': True})

encoding: 使用默认的 'utf-8' 就行。

dont_filter: indicates that this request should not be filtered by the scheduler.

This is used when you want to perform an identical request multiple times,

to ignore the duplicates filter. Use it with care, or you will get into crawling loops.

Default to False.

errback: 指定错误处理函数

2.6 接下来就是 Response 的源码:

# 部分代码

class Response(object_ref):

def __init__(self, url, status=200, headers=None, body='', flags=None, request=None):

self.headers = Headers(headers or {})

self.status = int(status)

self._set_body(body)

self._set_url(url)

self.request = request

self.flags = [] if flags is None else list(flags)

@property

def meta(self):

try:

return self.request.meta

except AttributeError:

raise AttributeError("Response.meta not available, this response " \

"is not tied to any request")复制代码参数跟上面的类似。

2.7 在继续向下看:

# 第二个方法

def parse_item(self, response):

item = MyItem()

# populate `item` fields

# 相当于导航栏下面的列表页,此时可能还存在分页情况

# and extract item_details_url

yield scrapy.Request(item_details_url, self.parse_details, meta={'item': item})复制代码说明:

a) 接收到第一个方法得到并遍历的所有url的请求响应Response。并在当前页面中查找了所有的详细实体的初略信息,以及单品详细的url地址。此时需要继续向下请求,请求详细的实体的页面。

b) 在这个方法中使用到了 item,也可以不使用。直接将信息(比如实体根据导航标签的大体分类),通过Request的meta属性,传递给下一个callback处理函数。

2.8 继续向下看:

# 第三个方法

def parse_details(self, response):

item = response.meta['item']

# populate more `item` fields

return item复制代码说明:此时,请求已经得到了实体的具体页面,也就是实体详细页。(比如,根据商品的列表进入了详情)。

这时需要接收一下,从上一个方法中传递过来的信息。

def parse_details(self, response):

item = response.meta['item']

# 也可以使用如下方式,设置一个默认值

item = response.meta.get('item', None)

# 当 'item' key 不存在 meta字典中时,返回None复制代码说明:

最后将最终得到的 item 返回,这样就能在  ITEM_PIPELINES 中得到数据,并进行下一步的处理了

3. 下一步

现在网页上使用javascript实在太普遍

a) 研究一下怎样在Scrapy中加入加载javascript页面的代码

b) 加载和处理javascript页面,会不会造成阻塞

4,文档修改历史

2016-06-17:V1.0,首次发布

python爬虫之request_Python爬虫:Scrapy研读之Request/Reponse相关推荐

  1. python 爬虫 scrapy 和 requsts 哪个快_Python爬虫:Scrapy研读之Request/Reponse

    本帖最后由 shenzhenwan10 于 2016-6-17 07:52 编辑 1,引言 在前一篇Scrapy:python3下的第一次运行测试 中,我们以官网的tutorial为例,成功的运行了S ...

  2. python爬虫模块request_Python爬虫——Request模块

    文章说明了Request模块的意义, 且强调了Request模块使用更加方便. 接下来介绍几种常用的Request操作,并且会在后续补充说明一些特定用法. 导入文件 import requests 一 ...

  3. python爬虫scrapy框架教程_Python爬虫教程-30-Scrapy 爬虫框架介绍

    从本篇开始学习 Scrapy 爬虫框架 Python爬虫教程-30-Scrapy 爬虫框架介绍 框架:框架就是对于相同的相似的部分,代码做到不出错,而我们就可以将注意力放到我们自己的部分了 常见爬虫框 ...

  4. python爬虫scrapy步骤mac系统_Mac中Python 3环境下安装scrapy的方法教程

    前言 最近抽空想学习一下python的爬虫框架scrapy,在mac下安装的时候遇到了问题,逐一解决了问题,分享一下,话不多说了,来一起看看详细的介绍吧. 步骤如下: # 在Mac上Python3环境 ...

  5. python爬虫实战:利用scrapy,短短50行代码下载整站短视频

    近日,有朋友向我求助一件小事儿,他在一个短视频app上看到一个好玩儿的段子,想下载下来,可死活找不到下载的方法.这忙我得帮,少不得就抓包分析了一下这个app,找到了视频的下载链接,帮他解决了这个小问题 ...

  6. linux scrapy 定时任务_写爬虫一定要会scrapy?-Python每日3题(爬虫专题)

    这里是Python7编程挑战-爬虫专题! 每天学习3个问题,包括初级,中级,高级问题各1个. 今天是第2天!一起来呀,就7天! 每日3题是麦叔的面试系列专题之一,每天包括初级,中级,高级难度题目各一道 ...

  7. 【Python笔记】网络爬虫——常用框架介绍以及 Scrapy 框架使用

    网络爬虫开发常用框架 Scrapy 爬虫框架 Crawley 爬虫框架 PySpider 爬虫框架 Scrapy 爬虫框架的使用 搭建 Scrapy 爬虫框架 1. 安装 Twisted 模块 2. ...

  8. python爬虫框架学习_学习Python爬虫必备框架:Scrapy

    一 介绍 Scrapy一个开源和协作的框架,其最初是为了页面抓取 (更确切来说, 网络抓取 )所设计的,使用它可以以快速.简单.可扩展的方式从网站中提取所需的数据. 但目前Scrapy的用途十分广泛, ...

  9. python爬虫的基本原理以及scrapy框架的使用

    正则表达式基础 正则表达式用于处理字符串,拥有自己独立的语法以及一个独立的处理引擎. 不同提供正则表达式的语言里正则表达式的语法都式一样. . 和 * + . 匹配任意一个字符 *匹配0或多次前面出现 ...

最新文章

  1. mysql gtid 1236_MYSQL主从搭建GTID报错 error 1236 master has purged binary logs containing GTIDs?...
  2. Java Vector
  3. 蓝桥杯_算法训练_大小写转换
  4. SAP MM 评估类型 评估类别
  5. html请求接口_通用网关接口-FastCGI介绍
  6. VHDL实现打地鼠游戏设计
  7. java程会释放锁join_关于join() 是否会释放锁的一些思考
  8. linux中samba启动不了,Linux_RHEL5中不用关闭SELinux而成功启动Samba,RHEL5中的samba服务器启动后,能 - phpStudy...
  9. 什么可以作为gcroot_面包果既能当水果又可以作为粮食,国内却无法普及,这是为什么?...
  10. 明明的随机数冒泡排序c 语言,NOIP复赛 c++-明明的随机数(算法和原码参考)
  11. python二级考试报名2020浙江_关于2020年下半年高校计算机等级考试报名的通知
  12. hdu 2069 1 5 10 25 50 这几种硬币 一共100个(母函数)
  13. 【批处理学习笔记】第二十五课:间接传递
  14. 软件测试测试用例编写 不超过7步骤_软件测试(功能、接口、性能、自动化)详解...
  15. 音乐社交APP源码项目
  16. 数据库加密sqlite3
  17. SAS univariate过程
  18. [OpenGL] 几何着色器
  19. 那些在一个公司死磕了5-10年的人,最后都怎么样了?那些在一个公司死磕了5-10年的人,最后都怎么样了?...
  20. 二维数组作为参数传递问题

热门文章

  1. 聊聊rocketmq的ConsumerIdsChangeListener
  2. 【Python爬虫】Beautiful Soup库入门
  3. 【MATLAB】主要功能
  4. JAVA对接支付宝支付(超详细,一看就懂)
  5. 字符url编码_HTML URL编码字符参考
  6. 2020年用于前端开发的顶级JavaScript框架
  7. 传智播客 c#_播客#46:Alexander Kallaway
  8. react 组件中使用组件_禁止使用React功能组件的7个理由
  9. retrofit2.6.0_RxAndroid和Retrofit 2.0
  10. 杭电oj 1000 c++ 版本