scrapy爬蟲學習系列二:scrapy簡單爬蟲樣例學習


系列文章列表:

scrapy爬蟲學習系列一:scrapy爬蟲環境的准備:       http://www.cnblogs.com/zhaojiedi1992/p/zhaojiedi_python_007_scrapy01.html

scrapy爬蟲學習系列二:scrapy簡單爬蟲樣例學習:  http://www.cnblogs.com/zhaojiedi1992/p/zhaojiedi_python_007_scrapy02.html

scrapy爬蟲學習系列三:scrapy部署到scrapyhub上:   http://www.cnblogs.com/zhaojiedi1992/p/zhaojiedi_python_004_scrapyhub.html

scrapy爬蟲學習系列四:portia的學習入門:       http://www.cnblogs.com/zhaojiedi1992/p/zhaojiedi_python_010_scrapy04.html

scrapy爬蟲學習系列五:圖片的抓取和下載:                 http://www.cnblogs.com/zhaojiedi1992/p/zhaojiedi_python_011_scrapy05.html

 

scrapyhub上有些視頻簡單介紹scrapy如何學習的(貌似要翻牆):https://helpdesk.scrapinghub.com/support/solutions/articles/22000201028-learn-scrapy-video-tutorials-

本博客的源碼下載地址(github) :https://github.com/zhaojiedi1992/tutorial

在上一個學習系列一種, 我們簡單了解了小scrapy的一些概念和基本環境的搭建,接下來就開始創建工程和爬蟲吧。

1 創建工程

 1.1先創建一個目錄,用於我們后續的scrapy目錄(e:\scrapytest)

Win+R 快捷鍵 輸入cmd 啟動一個cmd創建,進行一下輸入。
C:\Users\Administrator>e: E:\>cd e:\scrapytest e:\scrapytest>scrapy startproject tutorial New Scrapy project 'tutorial', using template directory 'C:\\Program Files\\Anaconda3\\lib\\site-packages\\scrapy\\templates\\project', created in: e:\scrapytest\tutorial You can start your first spider with: cd tutorial scrapy genspider example example.com e:\scrapytest>

我們發現使用scrapy startproject tutorial 給我們創建了許多文件,文件樹結構如下:

e:\scrapytest>tree  /f
卷 新加卷 的文件夾 PATH 列表
卷序列號為 0000004B D20B:7155
E:.
└─tutorial
    │  scrapy.cfg                    #開發配置文件
    │
    └─tutorial                       #工程模塊
        │  items.py            
        │  middlewares.py       #定義數據條目的定義,可以理解為一行記錄
        │  pipelines.py        #定義數據導出類,用於數據導出
        │  settings.py         #工程設置文件
        │  __init__.py        #空文件
        │
        ├─spiders           #爬蟲目錄,用於放置各種爬蟲類文件
        │  │  __init__.py      #空文件
        │  │
        │  └─__pycache__       #這個文件不用管它
        └─__pycache__          #這個文件不用管它

通過上面的一條簡單的命令,我們就創建了一個工程,有了工程,沒有爬蟲啊,接下里我們就創建一個爬蟲吧。

2 創建爬蟲

我們使用scrapy genspider quotes quotes.toscrape.com去創建一個爬蟲。

scrapy genspider 使用方法: scrapy genspider [options] <name> <domain>

可以使用scrapy genspider -h 獲取詳細幫助 或者從官方獲取shell幫助https://docs.scrapy.org/en/latest/topics/commands.html

e:\scrapytest\tutorial>scrapy genspider quotes quotes.toscrape.com
Created spider 'quotes' using template 'basic' in module:
  tutorial.spiders.quotes

注意:使用pycharm 打開tutorial項目,需要對python的環境進行設置(我機器上python環境太多了),使用File->Settings->Project:tutorial->Project Interpreter 選擇我們特定的python.exe。如下圖:

3 完善我們的爬蟲

修改我們的爬蟲文件(quotes.py)內容如下:

# -*- coding: utf-8 -*-
import scrapy


class QuotesSpider(scrapy.Spider):
    name = "quotes"
    allowed_domains = ["http://quotes.toscrape.com/"]
    start_urls = ['http://quotes.toscrape.com/page/1/']

    def parse(self, response):
        filename="source.html"
        with open(filename,'wb') as f:
            f.write(response.body)

代碼簡單介紹下吧:

  • name:設定了爬蟲的名字
  • allowed_domains :設定允許域,不是這些域內的網址就會被放棄。
  • start_urls:就是爬蟲程序初始的url集合。
  • parse:默認處理response流的方法,通常會返回一個item或者dict 給pipeline。

現在,工程有了,爬蟲也有了。 接下里開始讓我們的爬蟲進行工作吧。

4 運行爬蟲

運行爬蟲很簡單,使用scrapy crawl quotes 命令就可以里

e:\scrapytest\tutorial>scrapy crawl quotes
2017-08-25 22:50:25 [scrapy.utils.log] INFO: Scrapy 1.3.3 started (bot: tutorial)
2017-08-25 22:50:25 [scrapy.utils.log] INFO: Overridden settings: {'BOT_NAME': 'tutorial', 'NEWSPIDER_MODULE': 'tutorial.spiders', 'ROBOTSTXT_OBEY': True, 'SPIDER_MODULES': ['tutorial.spiders']}
2017-08-25 22:50:25 [scrapy.middleware] INFO: Enabled extensions:
['scrapy.extensions.corestats.CoreStats',
 'scrapy.extensions.telnet.TelnetConsole',
 'scrapy.extensions.logstats.LogStats']
2017-08-25 22:50:26 [scrapy.middleware] INFO: Enabled downloader middlewares:
['scrapy.downloadermiddlewares.robotstxt.RobotsTxtMiddleware',
 'scrapy.downloadermiddlewares.httpauth.HttpAuthMiddleware',
 'scrapy.downloadermiddlewares.downloadtimeout.DownloadTimeoutMiddleware',
 'scrapy.downloadermiddlewares.defaultheaders.DefaultHeadersMiddleware',
 'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware',
 'scrapy.downloadermiddlewares.retry.RetryMiddleware',
 'scrapy.downloadermiddlewares.redirect.MetaRefreshMiddleware',
 'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware',
 'scrapy.downloadermiddlewares.redirect.RedirectMiddleware',
 'scrapy.downloadermiddlewares.cookies.CookiesMiddleware',
 'scrapy.downloadermiddlewares.stats.DownloaderStats']
2017-08-25 22:50:26 [scrapy.middleware] INFO: Enabled spider middlewares:
['scrapy.spidermiddlewares.httperror.HttpErrorMiddleware',
 'scrapy.spidermiddlewares.offsite.OffsiteMiddleware',
 'scrapy.spidermiddlewares.referer.RefererMiddleware',
 'scrapy.spidermiddlewares.urllength.UrlLengthMiddleware',
 'scrapy.spidermiddlewares.depth.DepthMiddleware']
2017-08-25 22:50:26 [scrapy.middleware] INFO: Enabled item pipelines:
[]
2017-08-25 22:50:26 [scrapy.core.engine] INFO: Spider opened
2017-08-25 22:50:26 [scrapy.extensions.logstats] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min)
2017-08-25 22:50:26 [scrapy.extensions.telnet] DEBUG: Telnet console listening on 127.0.0.1:6023
2017-08-25 22:50:27 [scrapy.core.engine] DEBUG: Crawled (404) <GET http://quotes.toscrape.com/robots.txt> (referer: None)
2017-08-25 22:50:27 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://quotes.toscrape.com/page/1/> (referer: None)
2017-08-25 22:50:28 [scrapy.core.engine] INFO: Closing spider (finished)
2017-08-25 22:50:28 [scrapy.statscollectors] INFO: Dumping Scrapy stats:
{'downloader/request_bytes': 451,
 'downloader/request_count': 2,
 'downloader/request_method_count/GET': 2,
 'downloader/response_bytes': 2701,
 'downloader/response_count': 2,
 'downloader/response_status_count/200': 1,
 'downloader/response_status_count/404': 1,
 'finish_reason': 'finished',
 'finish_time': datetime.datetime(2017, 8, 25, 14, 50, 28, 49601),
 'log_count/DEBUG': 3,
 'log_count/INFO': 7,
 'response_received_count': 2,
 'scheduler/dequeued': 1,
 'scheduler/dequeued/memory': 1,
 'scheduler/enqueued': 1,
 'scheduler/enqueued/memory': 1,
 'start_time': datetime.datetime(2017, 8, 25, 14, 50, 26, 788397)}
2017-08-25 22:50:28 [scrapy.core.engine] INFO: Spider closed (finished)

運行爬蟲后, 會提示一堆的信息,主要是完成以下幾個部分工作:

  • 啟動爬蟲引擎
  • 加載設置文件
  • 啟用擴展
  • 啟用下載中間件
  • 啟用爬蟲中間件
  • 啟動pipeline
  • 爬蟲啟動,開始工作
  • 爬蟲結束, 引擎收集統計信息,清理工作

我們的爬蟲代碼是簡單,就是打開一個sour.html文件,把獲取的響應流(response)的頁面內容寫入進去。

到這這里,我們的爬蟲只是獲取了網址的源碼,可能不是我們真正關心的,我們還需要寫一寫提取規則,提取網站的有用的信息(比如這個網址,我們只需要提取出作者,他的名言,他的標簽),那我們就修改完善下爬蟲吧。

5 完善爬蟲

5.1 網址分析

我們自己用瀏覽器打開http://quotes.toscrape.com/page/1/ 這個網址,發現網頁比較規整,核心的內容區域包含3個內容出作者,他的名言,他的標簽。

 5.2 使用瀏覽器調試功能(f12)獲取元素的css樣式。

5.3 在item,py 文件修改為如下的內容

# -*- coding: utf-8 -*-

# Define here the models for your scraped items
#
# See documentation in:
# http://doc.scrapy.org/en/latest/topics/items.html

import scrapy


class TutorialItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    author=scrapy.Field()
    text=scrapy.Field()
    tags=scrapy.Field()
    pass

代碼簡介:我們創建了3個字段,分別用於存儲網址上的名言,作者和標記信息。

5.4 完善我們的爬蟲

修改我們的爬蟲為如下代碼:

# -*- coding: utf-8 -*-
import scrapy
from ..items import  TutorialItem

class QuotesSpider(scrapy.Spider):
    name = "quotes"
    allowed_domains = ["http://quotes.toscrape.com/"]
    start_urls = ['http://quotes.toscrape.com/page/1/']

    def parse(self, response):
        for quote in response.css('div.quote'):
            elem=TutorialItem()
            elem["text"]=quote.css('span.text::text').extract_first()
            elem["author"]=quote.css('small.author::text').extract_first()
            elem["tags"]=quote.css('div.tags a.tag::text').extract()
            yield  elem

代碼簡介: 寫一個for循環去遍歷,每次提取一個elem,使用css選擇器去定位元素。當然你也可以使用xpath去定位元素。

關於css選擇器的如何使用:可以參考如下網址

w3cschool : http://www.w3school.com.cn/cssref/css_selectors.asp

官方文檔:https://docs.scrapy.org/en/latest/topics/selectors.html

6 存儲我們的數據

我們啟動爬蟲的時候,加入-o選項,可以指定輸出, 它可以根據文件后綴判斷出你要導出的格式。默認的導出目錄是基於工程目錄的,也就是說你設置-o quotes.json 會在你的工程目錄下生成一個quotes.json文件。

e:\scrapytest\tutorial>scrapy crawl quotes -o quotes.json
e:\scrapytest\tutorial>scrapy crawl quotes -o quotes.xml
e:\scrapytest\tutorial>scrapy crawl quotes -o quotes.csv
e:\scrapytest\tutorial>scrapy crawl quotes -o quotes.jl

這里我是實在命令行指定-o選項,導出的,能不能不在命令行設置就可以導出呢,當然可以了,修改我們的pipeline吧。

7 修改pipeline

pipeline從其名字就知意,管道行用於對輸入的數據(item)進行清洗和持久化處理。

修改pipeline.py內容如下:

# -*- coding: utf-8 -*-

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html


class TutorialPipeline(object):
    def process_item(self, item, spider):
        return item

import json

class JsonWriterPipeline(object):

    def open_spider(self, spider):
        self.file = open('items.jl', 'w')

    def close_spider(self, spider):
        self.file.close()

    def process_item(self, item, spider):
        line = json.dumps(dict(item)) + "\n"
        self.file.write(line)
        return item

設置好一個jsonline的pipline后,怎么讓他生效呢, 需要在setting文件啟用它的。

8 啟用指定pipeline

打開setting.py文件

啟用如下如下注釋行,並稍作修改。

ITEM_PIPELINES = {
    'tutorial.pipelines.JsonWriterPipeline': 300,
}

9 再次運行爬蟲

這次在運行爬蟲,我們發現生成了一個items.jl文件。當然了,我們這里是把items持久化到文件中去了,我們也是可以修改pipeline添加一個pipeline讓item數據持久化到數據庫中去。官方的一個樣例:https://docs.scrapy.org/en/latest/topics/item-pipeline.html#write-items-to-mongodb

如果想生成各種格式的,處理feedback技術,可以參考我另一篇文章: http://www.cnblogs.com/zhaojiedi1992/p/zhaojiedi_python_005_scrapy.html

10 鏈接追蹤

可以看到我們的爬蟲只是爬取了page=1的內容,我要是想提取所有page的內容呢。如果你仔細分析下網頁,可以看到page=1的頁面最下面有個next的超鏈接指向下一頁的。

那我們修改我們的爬蟲代碼為如下:

 

# -*- coding: utf-8 -*-
import scrapy
from ..items import  TutorialItem


class QuotesSpider(scrapy.Spider):
    name = "quotes"
    allowed_domains = ["http://quotes.toscrape.com/"]
    start_urls = ['http://quotes.toscrape.com/page/1/']

    def parse(self, response):
        for quote in response.css('div.quote'):
            elem=TutorialItem()
            elem["text"]=quote.css('span.text::text').extract_first()
            elem["author"]=quote.css('small.author::text').extract_first()
            elem["tags"]=quote.css('div.tags a.tag::text').extract()
            yield elem
        next_page = response.css('li.next a::attr(href)').extract_first()
        if next_page is not None:
            next_page = response.urljoin(next_page)
            yield scrapy.Request(next_page, callback=self.parse,dont_filter=True)

 

代碼簡介:

next_page是我們從頁面提取的下一頁的網址,然后urljoin去拼接完整url,然后使用request去請求下一頁,還是使用parse去解析響應流,當然我們可以在寫一個parse的。

11 在次運行爬蟲

我們可以發現page1,page2的頁面的數據都提取出來,如下圖

 12 給爬蟲添加參數

  我們想運行爬蟲的時候,想給他指定一個參數,比如傳遞一個page號,讓他動態去設置一個startul 可以嗎?

  修改quotes.py文件為如下內容:

 

# -*- coding: utf-8 -*-
import scrapy
from ..items import  TutorialItem


class QuotesSpider(scrapy.Spider):
    name = "quotes"
    allowed_domains = ["http://quotes.toscrape.com/"]
    #start_urls = ['http://quotes.toscrape.com/page/1/']
    def __init__(self, page=None, *args, **kwargs):
        super(QuotesSpider, self).__init__(*args, **kwargs)
        if isinstance(page, str):
            self.start_urls = [
                'http://quotes.toscrape.com/page/%s/' % page]
            self.page = page

    def parse(self, response):
        for quote in response.css('div.quote'):
            elem=TutorialItem()
            elem["text"]=quote.css('span.text::text').extract_first()
            elem["author"]=quote.css('small.author::text').extract_first()
            elem["tags"]=quote.css('div.tags a.tag::text').extract()
            yield elem
        next_page = response.css('li.next a::attr(href)').extract_first()
        if next_page is not None:
            next_page = response.urljoin(next_page)
            yield scrapy.Request(next_page, callback=self.parse ,dont_filter=True)

 

代碼簡介: 添加一個init方法,完成了page參數的賦值接受,設置了startu_urls。這樣就可以接受參數動態的生成start_urls了。

13 運行爬蟲

e:\scrapytest\tutorial>scrapy crawl quotes -a page=1

注: page=1,1就是參數,如果有空格使用雙引號引起來。

通過本文的學習,你應該了解了。 scrapy框架的大概流程了吧,items,pipeline,spider.py,settings 這些文件是如何協同工作的。

14 相關的參考

css學習: http://www.w3school.com.cn/cssref/css_selectors.asp,https://www.w3.org/TR/selectors

xpath學習: http://www.w3school.com.cn/xpath/xpath_functions.asp   , https://www.w3.org/TR/xpath

瀏覽器調試: https://docs.scrapy.org/en/latest/topics/firefox.html

瀏覽器插件推薦: chrom下cssfinder,xpathfinder ,selectorGadget , firefox下xpathfinder。 強烈推薦selectorGadget。

注意: 有時候設置css或者xpath表達式的時候建議在scrapy shell環境中先測試。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM