scrapy學習筆記(一)

環境:Windows 7  x64   Python3.7.1  pycharmhtml

1、安裝scrapy

1.1linux系統使用:pip install scrapypython

1.2Windows系統:linux

  • pip install wheel
  • 下載twisted http://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted  (根據Python的版本進行下載,這裏個人Python版本是3.7因此就下的3.7)
  • pip install 路徑\Twisted-19.2.1-cp37-cp37m-win_amd64
  • pip install pywin32
  • pip install scrapy

 2、建立scrapy項目

一、新建一個項目,選擇Python便可。我這裏建立的項目名是demo。建立好後是一個空的項目。數據庫

二、點擊pycharm下面的terminal,以下圖所示:api

在終端中輸入:scrapy startproject demo 命令,建立scrapy項目,建立成功後會出現以下目錄結構:網絡

各文件做用大體以下:dom

  • scrapy.cfg::項目的配置文件
  • demo/:該項目的python模塊。在此加入代碼。
  • demo/items.py:項目中的item文件主要用於定義數據的結構化存儲,相似於ORM中的models。
  • demo/pipelines.py:項目中的pipelines文件,指定數據的存儲方式(以文件的形式存儲,存儲到數據庫中)。
  • demo/settings.py:項目的設置文件.
  • demo/spiders/:放置spider代碼的目錄。咱們寫的爬蟲代碼在這個目錄下。

三、建立爬蟲文件

3.1在終端中輸入:cd demo(我這裏輸入demo是由於個人項目名是demo)scrapy

3.2在終端中輸入:scrapy genspider books books.toscrape.com  (scrapy genspider  應用名稱 爬取網頁的起始url)ide

 

 四、打開books文件,該文件結構以下:

五、爬取http://books.toscrape.com/的書籍信息。

5.1分析http://books.toscrape.com/頁面。函數

由上圖咱們能夠知道全部書籍都存放在div/ol/下的li標籤中。這裏咱們只打印書名,由此咱們能夠像下面這樣寫來提取數據。

5.2books中的部分代碼以下:

def parse(self, response):
        '''
        數據解析,提取。
        :param response: 爬取到的response對象
        :return:
        '''
        book_list = response.xpath('/html/body/div/div/div/div/section/div[2]/ol/li')
        for book in book_list:
            print(book.xpath('./article/div[1]/a/img/@alt').extract())

5.3在setting.py中配置以下:

USER_AGENT = 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67.0'   # UA頭
ROBOTSTXT_OBEY = False   # 若是爲True表示準信robots協議,則大多數數據都爬不了。因此這裏設置爲Flase
LOG_LEVEL = 'ERROR'  # 日誌等級

5.4在終端中執行爬取命令:scrapy crawl books

# 打印內容以下
['A Light in the Attic']
['Tipping the Velvet']
['Soumission']
['Sharp Objects']
['Sapiens: A Brief History of Humankind']
['The Requiem Red']
['The Dirty Little Secrets of Getting Your Dream Job']
['The Coming Woman: A Novel Based on the Life of the Infamous Feminist, Victoria Woodhull']
['The Boys in the Boat: Nine Americans and Their Epic Quest for Gold at the 1936 Berlin Olympics']
['The Black Maria']
['Starving Hearts (Triangular Trade Trilogy, #1)']
["Shakespeare's Sonnets"]
['Set Me Free']
["Scott Pilgrim's Precious Little Life (Scott Pilgrim #1)"]
['Rip it Up and Start Again']
['Our Band Could Be Your Life: Scenes from the American Indie Underground, 1981-1991']
['Olio']
['Mesaerion: The Best Science Fiction Stories 1800-1849']
['Libertarianism for Beginners']
["It's Only the Himalayas"]

由此咱們能夠看出這裏只是爬取了1頁,下面來爬取全部書籍名稱。

六、爬取全部頁面的書籍。

最終books.py的內容看起來像下面這樣:

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

class BooksSpider(scrapy.Spider):
    name = 'books'  # 爬蟲的惟一標識
    allowed_domains = ['books.toscrape.com']
    # 要爬取的起點,能夠是多個。
    start_urls = ['http://books.toscrape.com/']
    url = 'http://books.toscrape.com/catalogue/page-%d.html'   # url模板用於拼接新的url
    page_num = 2
    def parse(self, response):
        '''
        數據解析,提取。
        :param response: 爬取到的response對象
        :return:
        '''
        print(f'當前頁數{self.page_num}')  # 打印當前頁數的數據
        book_list = response.xpath('/html/body/div/div/div/div/section/div[2]/ol/li')
        for book in book_list:
            print(book.xpath('./article/div[1]/a/img/@alt').extract())
        if self.page_num < 50:  # 總共50頁的內容
            new_url = format(self.url % self.page_num)  # 拼接處新的URL
            self.page_num += 1  # 頁數加1
            yield scrapy.Request(url=new_url, callback=self.parse)  # 手動發送請求

在終端中執行命令獲取書名:scrapy crawl books

若是一切順利你會看到打印的最終部分結果以下:

今日小結:

  • 建立scrapy項目:scrapy startproject 爬蟲項目名稱。
  • 建立爬蟲應用:scrapy genspider books books.toscrape.com ((scrapy genspider  應用名稱 爬取網頁的起始url))應用名稱在整個項目中做爲惟一標識,不能出現同名的爬蟲應用。
  • 運行爬蟲程序:scrapy crawl books(scrapy  crawl  爬蟲應用)。
  • parse方法:當一個頁面下載完成後,Scrapy引擎會回調一個咱們指定的頁面解析函數(默認爲parse方法)解析頁面。一個頁面解析函數一般須要完成如下兩個任務:

    一、提取頁面中的數據(使用XPath或CSS選擇器)。
    二、提取頁面中的連接,併產生對連接頁面的下載請求。

  • 頁面解析函數一般被實現成一個生成器函數,每一項從頁面中提取的數據以及每個對連接頁面的下載請求都由yield語句提交給Scrapy引擎。

parse方法的工做機制(來源網絡):

  1. 由於使用的yield,而不是return。parse函數將會被當作一個生成器使用。scrapy會逐一獲取parse方法中生成的結果,並判斷該結果是一個什麼樣的類型;
  2. 若是是request則加入爬取隊列,若是是item類型則使用pipeline處理,其餘類型則返回錯誤信息。
  3. scrapy取到第一部分的request不會立馬就去發送這個request,只是把這個request放到隊列裏,而後接着從生成器裏獲取;
  4. 取盡第一部分的request,而後再獲取第二部分的item,取到item了,就會放到對應的pipeline裏處理;
  5. parse()方法做爲回調函數(callback)賦值給了Request,指定parse()方法來處理這些請求 scrapy.Request(url, callback=self.parse)
  6. Request對象通過調度,執行生成 scrapy.http.response()的響應對象,並送回給parse()方法,直到調度器中沒有Request(遞歸的思路)
  7. 取盡以後,parse()工做結束,引擎再根據隊列和pipelines中的內容去執行相應的操做;
  8. 程序在取得各個頁面的items前,會先處理完以前全部的request隊列裏的請求,而後再提取items。
  9. 這一切的一切,Scrapy引擎和調度器將負責到底。
相關文章
相關標籤/搜索