免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
Python 爬蟲(六):使用 Scrapy 爬取去哪兒網(wǎng)景區(qū)信息

目錄

Scrapy 是一個使用 Python 語言開發(fā),為了爬取網(wǎng)站數(shù)據(jù),提取結(jié)構(gòu)性數(shù)據(jù)而編寫的應(yīng)用框架,它用途廣泛,比如:數(shù)據(jù)挖掘、監(jiān)測和自動化測試。安裝使用終端命令 pip install Scrapy 即可。

Scrapy 比較吸引人的地方是:我們可以根據(jù)需求對其進行修改,它提供了多種類型的爬蟲基類,如:BaseSpider、sitemap 爬蟲等,新版本提供了對 web2.0 爬蟲的支持。

1 Scrapy 介紹

1.1 組成

  • Scrapy Engine(引擎):負責 Spider、ItemPipeline、Downloader、Scheduler 中間的通訊,信號、數(shù)據(jù)傳遞等。

  • Scheduler(調(diào)度器):負責接受引擎發(fā)送過來的 Request 請求,并按照一定的方式進行整理排列、入隊,當引擎需要時,交還給引擎。

  • Downloader(下載器):負責下載 Scrapy Engine(引擎) 發(fā)送的所有 Requests 請求,并將其獲取到的 Responses 交還給 Scrapy Engine(引擎),由引擎交給 Spider 來處理。

  • Spider(爬蟲):負責處理所有 Responses,從中解析提取數(shù)據(jù),獲取 Item 字段需要的數(shù)據(jù),并將需要跟進的 URL 提交給引擎,再次進入 Scheduler(調(diào)度器)。

  • Item Pipeline(管道):負責處理 Spider 中獲取到的 Item,并進行后期處理,如:詳細解析、過濾、存儲等。

  • Downloader Middlewares(下載中間件):一個可以自定義擴展下載功能的組件,如:設(shè)置代理、設(shè)置請求頭等。

  • Spider Middlewares(Spider 中間件):一個可以自定擴展和操作引擎和 Spider 中間通信的功能組件,如:自定義 request 請求、過濾 response 等。

總的來說就是:SpiderItem Pipeline 需要我們自己實現(xiàn),Downloader MiddlewaresSpider Middlewares 我們可以根據(jù)需求自定義。

1.2 流程梳理

1)Spider 將需要發(fā)送請求的 URL 交給 Scrapy Engine 交給調(diào)度器;

2)Scrapy Engine 將請求 URL 轉(zhuǎn)給 Scheduler

3)Scheduler 對請求進行排序整理等處理后返回給 Scrapy Engine;

4)Scrapy Engine 拿到請求后通過 Middlewares 發(fā)送給 Downloader

5)Downloader 向互聯(lián)網(wǎng)發(fā)送請求,在獲取到響應(yīng)后,又經(jīng)過 Middlewares 發(fā)送給 Scrapy Engine。

6)Scrapy Engine 獲取到響應(yīng)后,返回給 SpiderSpider 處理響應(yīng),并從中解析提取數(shù)據(jù);

7)Spider 將解析的數(shù)據(jù)經(jīng) Scrapy Engine 交給 Item Pipeline, Item Pipeline 對數(shù)據(jù)進行后期處理;

8)提取 URL 重新經(jīng) Scrapy Engine 交給Scheduler 進行下一個循環(huán),直到無 URL 請求結(jié)束。

1.3 Scrapy 去重機制

Scrapy 提供了對 request 的去重處理,去重類 RFPDupeFilterdupefilters.py 文件中,路徑為:Python安裝目錄\Lib\site-packages\scrapy ,該類里面有個方法 request_seen 方法,源碼如下:

def request_seen(self, request):    # 計算 request 的指紋    fp = self.request_fingerprint(request)    # 判斷指紋是否已經(jīng)存在    if fp in self.fingerprints:        # 存在        return True    # 不存在,加入到指紋集合中    self.fingerprints.add(fp)    if self.file:        self.file.write(fp + os.linesep)

它在 Scheduler 接受請求的時候被調(diào)用,進而調(diào)用 request_fingerprint 方法(為 request 生成一個指紋),源碼如下:

def request_fingerprint(request, include_headers=None):    if include_headers:        include_headers = tuple(to_bytes(h.lower())                                 for h in sorted(include_headers))    cache = _fingerprint_cache.setdefault(request, {})    if include_headers not in cache:        fp = hashlib.sha1()        fp.update(to_bytes(request.method))        fp.update(to_bytes(canonicalize_url(request.url)))        fp.update(request.body or b'')        if include_headers:            for hdr in include_headers:                if hdr in request.headers:                    fp.update(hdr)                    for v in request.headers.getlist(hdr):                        fp.update(v)        cache[include_headers] = fp.hexdigest()    return cache[include_headers]

在上面代碼中我們可以看到

fp = hashlib.sha1()...cache[include_headers] = fp.hexdigest()

它為每一個傳遞過來的 URL 生成一個固定長度的唯一的哈希值。再看一下 __init__ 方法,源碼如下:

def __init__(self, path=None, debug=False):	self.file = None	self.fingerprints = set()	self.logdupes = True	self.debug = debug	self.logger = logging.getLogger(__name__)	if path:		self.file = open(os.path.join(path, 'requests.seen'), 'a+')		self.file.seek(0)		self.fingerprints.update(x.rstrip() for x in self.file)

我們可以看到里面有 self.fingerprints = set() 這段代碼,就是通過 set 集合的特點(set 不允許有重復(fù)值)進行去重。

去重通過 dont_filter 參數(shù)設(shè)置,如圖所示

dont_filterFalse 開啟去重,為 True 不去重。

2 實現(xiàn)過程

制作 Scrapy 爬蟲需如下四步:

  • 創(chuàng)建項目 :創(chuàng)建一個爬蟲項目
  • 明確目標 :明確你想要抓取的目標(編寫 items.py)
  • 制作爬蟲 :制作爬蟲開始爬取網(wǎng)頁(編寫 xxspider.py)
  • 存儲內(nèi)容 :設(shè)計管道存儲爬取內(nèi)容(編寫pipelines.py)

我們以爬取去哪兒網(wǎng)北京景區(qū)信息為例,如圖所示:

2.1 創(chuàng)建項目

在我們需要新建項目的目錄,使用終端命令 scrapy startproject 項目名 創(chuàng)建項目,我創(chuàng)建的目錄結(jié)構(gòu)如圖所示:

  • spiders 存放爬蟲的文件
  • items.py 定義數(shù)據(jù)類型
  • middleware.py 存放中間件
  • piplines.py 存放數(shù)據(jù)的有關(guān)操作
  • settings.py 配置文件
  • scrapy.cfg 總的控制文件

2.2 定義 Item

Item 是保存爬取數(shù)據(jù)的容器,使用的方法和字典差不多。我們計劃提取的信息包括:area(區(qū)域)、sight(景點)、level(等級)、price(價格),在 items.py 定義信息,源碼如下:

import scrapyclass TicketspiderItem(scrapy.Item):    area = scrapy.Field()    sight = scrapy.Field()    level = scrapy.Field()    price = scrapy.Field()    pass

2.3 爬蟲實現(xiàn)

在 spiders 目錄下使用終端命令 scrapy genspider 文件名 要爬取的網(wǎng)址 創(chuàng)建爬蟲文件,然后對其修改及編寫爬取的具體實現(xiàn),源碼如下:

import scrapyfrom ticketSpider.items import TicketspiderItemclass QunarSpider(scrapy.Spider):    name = 'qunar'    allowed_domains = ['piao.qunar.com']    start_urls = ['https://piao.qunar.com/ticket/list.htm?keyword=%E5%8C%97%E4%BA%AC&region=&from=mpl_search_suggest']    def parse(self, response):        sight_items = response.css('#search-list .sight_item')        for sight_item in sight_items:            item = TicketspiderItem()            item['area'] = sight_item.css('::attr(data-districts)').extract_first()            item['sight'] = sight_item.css('::attr(data-sight-name)').extract_first()            item['level'] = sight_item.css('.level::text').extract_first()            item['price'] = sight_item.css('.sight_item_price em::text').extract_first()            yield item        # 翻頁        next_url = response.css('.next::attr(href)').extract_first()        if next_url:            next_url = "https://piao.qunar.com" + next_url            yield scrapy.Request(                next_url,                callback=self.parse            )

簡單介紹一下:

  • name:爬蟲名
  • allowed_domains:允許爬取的域名
  • atart_urls:爬取網(wǎng)站初始請求的 url(可定義多個)
  • parse 方法:解析網(wǎng)頁的方法
  • response 參數(shù):請求網(wǎng)頁后返回的內(nèi)容

yield

在上面的代碼中我們看到有個 yield,簡單說一下,yield 是一個關(guān)鍵字,作用和 return 差不多,差別在于 yield 返回的是一個生成器(在 Python 中,一邊循環(huán)一邊計算的機制,稱為生成器),它的作用是:有利于減小服務(wù)器資源,在列表中所有數(shù)據(jù)存入內(nèi)存,而生成器相當于一種方法而不是具體的信息,占用內(nèi)存小。

爬蟲偽裝

通常需要對爬蟲進行一些偽裝,關(guān)于爬蟲偽裝可通過【Python 爬蟲(一):爬蟲偽裝】做一下簡單了解,這里我們使用一個最簡單的方法處理一下。

  • 使用終端命令 pip install scrapy-fake-useragent 安裝
  • 在 settings.py 文件中添加如下代碼:
DOWNLOADER_MIDDLEWARES = {    # 關(guān)閉默認方法    'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware': None,     # 開啟    'scrapy_fake_useragent.middleware.RandomUserAgentMiddleware': 400, }

2.4 保存數(shù)據(jù)

我們將數(shù)據(jù)保存到本地的 csv 文件中,csv 具體操作可以參考:CSV 文件讀寫,下面看一下具體實現(xiàn)。

首先,在 pipelines.py 中編寫實現(xiàn),源碼如下:

import csvclass TicketspiderPipeline(object):    def __init__(self):        self.f = open('ticker.csv', 'w', encoding='utf-8', newline='')        self.fieldnames = ['area', 'sight', 'level', 'price']        self.writer = csv.DictWriter(self.f, fieldnames=self.fieldnames)        self.writer.writeheader()    def process_item(self, item, spider):        self.writer.writerow(item)        return item    def close(self, spider):        self.f.close()

然后,將 settings.py 文件中如下代碼:

ITEM_PIPELINES = {    'ticketSpider.pipelines.TicketspiderPipeline': 300,}

放開即可。

2.5 運行

我們在 settings.py 的同級目錄下創(chuàng)建運行文件,名字自定義,放入如下代碼:

from scrapy.cmdline import executeexecute('scrapy crawl 爬蟲名'.split())

這個爬蟲名就是我們之前在爬蟲文件中的 name 屬性值,最后在 Pycharm 運行該文件即可。

參考:

http://www.scrapyd.cn/doc/
https://www.liaoxuefeng.com/wiki/897692888725344/923029685138624

完整代碼請關(guān)注文末公眾號,后臺回復(fù) qs 獲取。



本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
利用scrapy爬取豆瓣250
從原理到實戰(zhàn),一份詳實的 Scrapy 爬蟲教程,值得收藏
【實戰(zhàn)視頻】使用scrapy寫爬蟲-爬知乎live
軟微蟲師帶你一天入門分布式網(wǎng)絡(luò)爬蟲
網(wǎng)頁爬蟲
5分鐘快速掌握 scrapy 爬蟲框架
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服