python爬蟲框架之scrapy的快速上手


下載與安裝

pip install scrapy

創建項目

scrapy startproject 項目名稱

這里我們指定的項目名稱為Spider,執行完創建項目的命令后,得到的提示為:

You can start your first spider with:
      cd Spider
      scrapy genspider example example.com

然后按照提示,依次來執行這兩行命令。
這里,cd命令是切換到當前爬蟲的工作目錄。
genspider 則是生成一個爬蟲,該爬蟲的名字為example,要爬取的網站為example.com。
當然,example和example.com 可以根據實際情況進行修改。

執行完生成爬蟲的命令后,我們可以看到如下提示:

Created spider 'example' using template 'basic' in module:
  Spider.spiders.example

從提示中可以看到,這里使用了‘basic’模板來生成爬蟲,當然可以指定別的模板
關於另一個模板-crawl請見https://www.cnblogs.com/ASE265/p/12363843.html
最終,我們得到的這整個項目的框架為:

Spider
    spiders
        _init_.py
        example.py
    _init_.py
    items.py
    middleswares.py
    pipelines.py
    settings.py
scrapy.cfg

這些文件分別是:

  • scrapy.cfg:項目配置的文件
  • Spider:該項目的python模塊,該文件夾的名字為startproject命令指定的名字
  • items.py:項目的item文件
  • pipilines.py:項目的管道文件
  • settings.py:項目的設置文件
  • spiders:放置爬蟲代碼的文件夾
  • spiders/example.py:爬蟲文件

example.py文件

不同的模板生成的文件是不一樣的,這里的example.py文件對應於‘basic’模板。

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

class ExampleSpider(scrapy.Spider):
    name = 'example'
    allowed_domains = ['example.com']
    start_urls = ['http://example.com/']

    def parse(self, response):
        pass

可以看到,該文件定義了一個爬蟲類ExampleSpider,它繼承於Spider類,各個屬性和方法的定義如下:

  • name:爬蟲的名字,定義了Scrapy如何定義並初始化spider,非常重要的屬性
  • allowed_domains:指定允許爬取的域名列表
  • start_url:當沒有指定特定的URL時,爬蟲將從該列表中開始進行爬取 另:在start_url中的url不屬於指定URL
  • parse函數:則是對請求start_url返回的response對象進行分析,該函數需要用戶自定義。

至於怎么根據start_url來發出請求我們實際上並不用關心
事實上,Scrapy是有意對其進行了封裝
Spider類有一個start_requests()方法
該方法的默認實現是使用 start_urls 的url生成Request
可對該方法進行重寫,但大可不必

Spider類還提供了一個make_requests_from_url(url)方法,
當spider啟動爬取並指定了URL時,make_requests_from_url()將被調用來創建Request對象
該方法接受一個URL並返回用於爬取的Request對象,也可以對該方法進行重寫
另:在看源碼的時候發現該方法已被棄用,以后的版本將不再使用該方法

例子:新浪新聞的簡單爬取

這里,假設我們已經對新浪新聞網站進行了分析,並決定爬取新浪新聞里的滾動新聞里的國內新聞版塊。
為了不與之前的example搞混,我們根據上述的流程重新創建一個用於爬取新浪新聞的爬蟲。
具體實現的功能是爬取共爬取10頁的所有新聞鏈接,然后再根據得到的新聞鏈接爬取對應的新聞
並將新聞的標題,內容和發布時間等信息保存下來。

因此,在我們的爬蟲文件中,設置的參數如下:

name = 'sina'
allowed_domains = ['feed.mix.sina.com.cn','sina.com.cn']
start_urls = ["https://feed.mix.sina.com.cn/api/roll/get?pageid=153&lid=2510&k=&num=50&page={}".format(page) for page in range(10)]

然后,決定我們需要爬取的內容
比如我們需要獲得每篇文章的標題,關鍵字,內容,發布的時間,媒體,標簽這些內容
因而需要對items.py文件進行設置,設置內容如下:

import scrapy

class SinaItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    title= scrapy.Field()
    keywords = scrapy.Field()
    time= scrapy.Field()
    media = scrapy.Field()
    content = scrapy.Field()
    tag= scrapy.Field()
    pass

然后,回到我們的爬蟲文件,將items.py的內容導入到爬蟲文件中
from Sina.items import SinaItem

parse函數的一個參數為:response
它是對start_url請求后獲得的一個response對象,就是包含了請求的網頁的信息
在這里,parse函數實現為:
在response中依次提取url,並將其拋給parsecontent函數
由parsecontent函數來處理請求該url后獲得的response的內容。

def parse(self, response):
    result = response.text
    data = json.loads(result).get('result').get('data')
    for news in data:
        url = news.get('url')
        yield scrapy.Request(url, callback=self.parsecontents)

parseconten函數的內容為根據請求url后返回的response內容進行提取
另:使用xpath對網頁格式的內容提取非常方便,推薦使用

def parsecontents(self,response):
    title = response.xpath('//title/text()').extract()[0]
    meta = response.xpath('//meta/@content').extract()
    keywords = meta[2]
    time = meta[10]
    media = meta[13]
    paragraph = response.xpath('//div[@class="article"]/p/text()').extract()
    content = ""
    for p in paragraph:
        content = content + p
    item = SinaItem()
    item['title'] = str(title)
    item['keywords'] = str(keywords)
    item['time'] = str(time)
    item['media'] = str(media)
    item['content'] = str(content)
    item['tag'] = "news"
    yield item

爬蟲運行

在工作目錄下輸入命令以啟動爬蟲

scrapy crawl 爬蟲名稱

這里輸入的命令為:scrapy crawl sina

內容保存

爬蟲爬取的內容保存實現在pipelines.py文件,在編寫爬蟲時,我們最后拋出了item。
這個item最后被傳送得到了pipelines.py中
在pipelines.py文件中,我們可以實現將獲取的item寫入文件或者保存得到MongoDB數據庫中。

爬蟲結果

爬取得到的內容為:

爬取結束后,scrapy會給出統計信息

代碼

具體代碼,請見github


免責聲明!

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



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