日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

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

發布時間:2024/10/8 python 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python 爬虫 scrapy 和 requsts 哪个快_Python爬虫:Scrapy研读之Request/Reponse 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本帖最后由 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 爬虫 scrapy 和 requsts 哪个快_Python爬虫:Scrapy研读之Request/Reponse的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。