Python爬蟲第十課:Scrapy框架(1)

前面的關卡中,我們學習瞭如何用協程來提升爬蟲的速度,並且通過項目實操,將協程運用於抓取HI運動的食物數據。

不知道你會不會有這樣一種感覺:要寫出一個完整的爬蟲程序需要做很多瑣碎的工作。比如,要針對不同的網站制定不同的解析方式;要導入不同功能的模塊;還要編寫各種爬取流程的代碼。

我們在日常工作中會使用PPT模板來製作PPT。那麼有沒有一個現成的爬蟲模板,讓我們能夠改之即用,也就是說對這個模板進行適當的修改,就能完成一個爬蟲項目的開發呢?

這種模板在Python中還真的存在,只不過我們一般稱之爲框架。

就像PPT模板會幫你設置好背景、字體和顏色一樣,一個爬蟲框架裏包含了能實現爬蟲整個流程的各種模塊,。

這一關,我們要學習的就是一個功能強大的爬蟲框架——Scrapy。

一、Scrapy是什麼

在我們之前的課程中,我們需要不同模塊實現不同的功能:使用requests模塊進行請求、使用csv模塊存儲數據等。而在Scrapy裏,你不需要這麼做,因爲很多爬蟲需要涉及的功能,比如麻煩的異步,在Scrapy框架都自動實現了

我們之前編寫爬蟲的方式,就相當於我們在自己裝修一個毛坯房。需要自己去找施工隊來「水電施工」「泥工砌牆貼磚」「木工吊頂打櫃子」「油漆工刷乳膠漆」等等…而框架就相當於一個精裝房,拎包入住!

1)Scrapy的結構

在這裏插入圖片描述
上面的這張圖是Scrapy的整個結構。你可以把整個Scrapy框架當成是你所在的部門。最中心位置的Scrapy Engine(引擎)就是你所在部門的大boss,負責統籌規劃你這個部門的四大職能。

以爬蟲流程的順序來依次介紹Scrapy爬蟲部門的4大職能:

  • Scheduler(調度器)主要負責處理引擎發送過來的requests對象(即網頁請求的相關信息集合,包括params,data,cookies,request headers…等),會把請求的url以有序的方式排列成隊,並等待引擎來提取(功能上類似於gevent庫的queue模塊)。

  • Downloader(下載器)則是負責處理引擎發送過來的requests,進行網頁爬取,並將返回的response(爬取到的內容)交給引擎。它對應的是爬蟲流程【獲取數據】這一步。

  • Spiders(爬蟲)的主要任務是創建requests對象和接受引擎發送過來的response(Downloader部門爬取到的內容),從中解析並提取出有用的數據。它對應的是爬蟲流程【解析數據】和【提取數據】這兩步。

  • Item Pipeline(數據管道)負責存儲和處理Spiders提取到的有用數據。這個對應的是爬蟲流程【存儲數據】這一步。

  • Downloader Middlewares(下載中間件)的工作相當於下載器的助手,比如會提前對引擎發送的諸多requests做出處理。

  • Spider Middlewares(爬蟲中間件)的工作則相當於爬蟲的助手,比如會提前接收並處理引擎發送來的response,過濾掉一些重複無用的東西。

在這裏插入圖片描述

3)Scrapy的工作原理

在這裏插入圖片描述
從這個圖中可以看出 Scrapy 框架的工作原理,即是——引擎就是大Boss,統領其他成員協同工作。

在使用 Scrapy 的時候。我們不需要去關心爬蟲的每個流程。並且Scrapy中的網絡請求都是默認異步模式,請求和返回都會由引擎去自動分配處理。

如果某個請求出現異常,框架也會幫我們做異常處理,跳過這個異常的請求,繼續去執行後面的程序。

所以說,我們使用 Scrapy 可以省掉很多的時間和工作!就像我們直接住進精裝房一樣!

二、Scrapy的用法

現在,我們已經初步瞭解Scrapy的結構以及工作原理。接下來,爲了熟悉Scrapy的用法,我們使用它來完成一個小項目——爬取豆瓣Top250圖書。

1)明確目標與分析過程

我們還是來遵循「項目實現」的三步驟:、

  1. 明確目標
  2. 分析過程
  3. 代碼實現

我們在代碼實現部分,重點講解Scrapy的使用方法。

明確目標,讓我們觀察一下要爬取的網站:https://book.douban.com/top250。豆瓣Top250圖書一共有10頁,每頁有25本書籍。

我們的初步目標是:先只爬取前三頁書籍的信息,總共是 25 x 3 = 75 本,包含書名、出版信息和書籍評分。

那就是分析要爬取的網頁結構。 既然我們要爬取書籍信息,我們就得先判斷這些信息被存在了哪裏。

右擊打開“檢查”工具,點開Network,刷新頁面,然後點擊第0個請求top250,看Response.

我們能在裏面找到書名、出版信息,說明我們想要的書籍信息就藏在這個網址的HTML裏。

https://book.douban.com/top250?start=25

我們可以看到,網址發生了變化,後面多了?start=25。現在的你,應該一眼就能猜到後面的數字應該是代表一頁的25本書籍吧?

你可以翻到第3頁,驗證一下猜想是不是正確的。

事實證明,我們猜對了。每翻一頁,網址後面的數字都會增加25,說明這個start的參數就是代表每頁的25本書籍。

我們要爬取的網址的構造規律就出來了。只要改變?start=後面的數字(翻一頁加25),我們就能得到每一頁的網址。

找到了網址的構造規律之後,我們就可以重點來分析HTML的結構,看看等下怎麼才能提取出我們想要的書籍信息。

還是是右擊打開“檢查”工具,點擊Elements,再點擊光標,把鼠標依次移到書名、出版信息、評分處,就能在HTML裏找到這些書籍信息。如下圖,《追風箏的人》的書籍信息就全部放在

標籤裏。
在這裏插入圖片描述
仔細觀察你就會發現,其實每一頁的25本書籍信息都分別藏在了一個
標籤裏。不過這個標籤沒有class屬性,也沒有id屬性,不方便我們提取信息。

我們得繼續再找一個既方便我們提取,又能包含所有書籍信息的標籤。

我們可以看看

標籤下的元素,好像剛好都能滿足我們的要求,既有class屬性,又包含了書籍的信息。

我們只要取出元素下元素的title屬性的值、

元素、元素,就能得到書名、出版信息和評分的數據。

頁面分析完畢,接着進入代碼實現的步驟,要開始寫 Scrapy 的代碼啦。

2)代碼實現——創建項目

如果你想着自己本地的電腦使用Scrapy,需要提前安裝好它。

  • Windows:在終端輸入命令:pip install scrapy;
  • mac:在終端輸入命令:pip3 install scrapy

創建Scrapy項目

首先,在本地電腦打開終端,然後跳轉到你想要保存項目的目錄下。

  • windows:Win+R,輸入cmd;
  • mac:command+空格,搜索“終端”

假設你想跳轉到D盤裏名爲Python文件夾中的scrapy_project子文件夾。

  1. 你需要再命令行輸入d:,就會跳轉到D盤
  2. 再輸入cd Python,就能跳轉到Python文件夾。
  3. 接着輸入cd scrapy_project,就能跳轉到Python文件夾裏的scrapy_project子文件夾。
  4. 再輸入一行能幫我們創建Scrapy項目的命令:scrapy startproject douban(douban就是Scrapy項目的名字)。按下enter鍵,一個Scrapy項目就創建成功了。

在mac系統中的終端裏,也是使用cd命令來跳轉到你要的文件夾位置

在這裏插入圖片描述
整個scrapy項目的結構,如下圖所示:
在這裏插入圖片描述
Scrapy項目裏每個文件都有它對應的具體功能。例如:

  • settings.py 是scrapy裏的各種設置
  • items.py是用來定義數據的
  • pipelines.py是用來處理數據的,它們對應的就是Scrapy的結構中的Item Pipeline(數據管道)。

如前所述,spiders是放置爬蟲的目錄。我們可以在spiders這個文件夾裏創建爬蟲文件。

我們來把這個文件,命名爲Book_douban_Top250。後面的大部分代碼都需要在這個Book_douban_Top250.py文件裏編寫。
在這裏插入圖片描述

代碼實現——編輯爬蟲

先在Book_douban_Top250.py文件裏導入我們需要的模塊。

import scrapy
import bs4
  • 導入BeautifulSoup用於解析和提取數據;
  • 導入scrapy是待會我們要用創建類的方式寫這個爬蟲,我們所創建的類將直接繼承scrapy中的scrapy.Spider類。這樣,有許多好用的屬性和方法,就能夠直接使用。

接着我們開始編寫爬蟲的核心代碼。

在Scrapy中,每個爬蟲的代碼結構基本都如下所示:

import scrapy
import bs4

class DoubanSpider(scrapy.Spider):
    name = 'book_douban'
    allowed_domains = ['book.douban.com']
    start_urls = ['https://book.douban.com/top250?start=0']
    
    def parse(self, response):
        print(response.text)

代碼解釋

  • 第1行代碼:定義一個爬蟲類DoubanSpider。就像我剛剛講過的那樣,DoubanSpider類繼承自scrapy.Spider類。

  • 第2行代碼:name是定義爬蟲的名字,這個名字是爬蟲的唯一標識。name = 'book_douban’意思是定義爬蟲的名字爲book_douban。等會我們啓動爬蟲的時候,要用到這個名字。

  • 第3行代碼:allowed_domains是定義允許爬蟲爬取的網址域名(不需要加https://)。如果網址的域名不在這個列表裏,就會被過濾掉。

    爲什麼會有這個設置呢?
    當你在爬取大量數據時,經常是從一個URL開始爬取,然後關聯爬取更多的網頁。
    假設我們在今天的爬蟲目標是爬豆瓣top250每本書籍的書評信息,我們會先爬取書單,再找到每本書的URL,再進入每本書的詳情頁面去抓取評論。
    allowed_domains就限制了我們這種關聯爬取的URL,一定在book.douban.com這個域名之下,不會跳轉到某個奇怪的廣告頁面。

  • 第4行代碼:start_urls是定義起始網址,就是爬蟲從哪個網址開始抓取。在此,allowed_domains的設定對start_urls裏的網址不會有影響。

  • 第5行代碼:parse是Scrapy裏默認處理response的一個方法。

是不是覺得和之前自己手動寫爬蟲的完全不一樣了呢?怎麼連 requests.get() 都沒有了呀?其實在框架裏,我們並不需要寫這一句。

scrapy框架會爲我們代勞做這件事,寫好你的請求,接下來你就可以直接寫對 response 如何做處理了。

豆瓣Top250圖書一共有10頁,每一頁的網址我們都知道。我們可以把10頁網址都塞進start_urls的列表裏。

在這裏插入圖片描述
我們可以利用豆瓣Top250圖書的網址規律,用for循環構造出每個網址,再把網址添加進start_urls的列表裏。
在這裏插入圖片描述
完善後的代碼如下:

import scrapy
import bs4


class DoubanSpider(scrapy.Spider):
    name = 'book_douban'
    allowed_domains = ['book.douban.com']
    start_urls = []
    for i in range(3):
        url = 'https://book.douban.com/top250?start={}'.format(i * 25)
        start_urls.append(url)

    def parse(self, response):
        print(response.text)

接下來,只要再借助DoubanSpider(scrapy.Spider)中的 parse 方法處理 response,藉助 BeautifulSoup 來取出我們想要的書籍信息的數據。這些在前面的課程我們都使用過,所以肯定是很熟練啦!

我們前面在分析項目過程的時候,已經知道書籍信息都藏在了哪些元素裏,現在可以利用find_all和find方法提取出來。比如,書名是元素下元素的title屬性的值;出版信息在

元素裏;評分在元素裏。

import scrapy
import bs4


# 定義一個爬蟲類DoubanSpider
class DoubanSpider(scrapy.Spider):
    # 定義爬蟲的名字
    name = 'book_douban'
    # 定義爬蟲的爬取的網址的域名
    allowed_domains = ['book.douban.com']
    # 定義起始網址
    start_urls = []
    # 將豆瓣Top250圖書的前3頁網址添加進start_urls列表中
    for i in range(3):
        url = 'https://book.douban.com/top250?start={}'.format(i * 25)
        start_urls.append(url)

    # parse是默認處理response的方法
    def parse(self, response):
        # 使用BeautifulSoup解析response
        bs = bs4.BeautifulSoup(response.text, 'html.parser')
        # 用find_all提取<tr class="item">元素,這個元素裏含有書籍信息。
        datas = bs.find_all('tr', class_='item')

        # 遍歷書籍信息列表
        for data in datas:
            # 取出書名
            title = data.find_all('a')[1].find('title')
            # 取出出版信息
            publish = data.find('p', class_='pl').text
            # 取出評分
            score = data.find('span', class_='rating_nums').text
            # 打印書籍信息
            print([title, publish, score])

按照之前寫爬蟲的方式,我們會把書名、出版信息、評分,分別賦值,然後統一做處理——或是打印,或是存儲。但在scrapy這裏,事情卻有所不同。

  • spiders(如Book_douban_Top250.py)只幹spiders應該做的事。對數據的後續處理,另有其他“部門”負責。

在scrapy中,我們會專門定義一個用於記錄數據的類。

當我們需要記錄數據的時候,比如前面在每一個最小循環裏,都要記錄“書名”,“出版信息”,“評分”。我們會實例化一個對象,利用這個對象來記錄數據。

定義這些數據類的python文件,正是items.py。

我們已經知道,我們要爬取的數據是書名、出版信息和評分。接下來讓我們在 items.py 中編寫這部分的代碼。

# 導入scrapy
import scrapy


# 定義一個類BookDoubanItem,它繼承自scrapy.Item
class BookDoubanItem(scrapy.Item):
    # 定義書名的數據屬性
    title = scrapy.Field()
    # 定義出版信息的數據屬性
    publish = scrapy.Field()
    # 定義評分的數據屬性
    score = scrapy.Field()

代碼解釋

  • 第1行代碼,我們導入了scrapy。因爲我們等會所創建的類將直接繼承scrapy中的scrapy.Item類。這樣,有很多好用屬性和方法,就能夠直接使用。比如,引擎能將item類的對象發給Item Pipeline(數據管道)處理。

  • 第3行代碼:我們定義了一個BookDoubanItem類。它繼承自scrapy.Item類。

  • 第5、7、9行代碼:我們定義了書名、出版信息和評分三種數據。scrapy.Field()這行代碼實現的是,讓數據能以類似字典的形式記錄。

下面的代碼展示了一下如何使用 BookDoubanItem:

# 導入scrapy
import scrapy


# 定義一個類BookDoubanItem,它繼承自scrapy.Item
class BookDoubanItem(scrapy.Item):
    # 定義書名的數據屬性
    title = scrapy.Field()
    # 定義出版信息的數據屬性
    publish = scrapy.Field()
    # 定義評分的數據屬性
    score = scrapy.Field()


# 實例化一個DoubanbookItem對象
book = BookDoubanItem()
book['title'] = '追風箏的人'
book['publish'] = '[美]卡勒德·胡塞尼 / 李繼宏 / 上海人民出版社 / 2006-5 / 29.00元'
book['score'] = '8.9'

print(book)
print(type(book))

# 輸出結果:
{'publish': '[美]卡勒德·胡塞尼 / 李繼宏 / 上海人民出版社 / 2006-5 / 29.00元',
 'score': '8.9',
 'title': '追風箏的人'}
<class '__main__.BookDoubanItem'>

你會看到打印出來的結果的確和字典非常相像,但它卻並不是dict,它的數據類型是我們定義的DoubanItem,屬於“自定義的Python字典”。

我們可以利用類似上述代碼的樣式,去重新寫Book_douban_Top250.py。如下所示:

import scrapy
import bs4
from ..items import BookDoubanItem

# 定義一個爬蟲類DoubanSpider
class DoubanSpider(scrapy.Spider):
    # 定義爬蟲的名字
    name = 'book_douban'
    # 定義爬蟲的爬取的網址的域名
    allowed_domains = ['book.douban.com']
    # 定義起始網址
    start_urls = []
    # 將豆瓣Top250圖書的前3頁網址添加進start_urls列表中
    for i in range(3):
        url = 'https://book.douban.com/top250?start={}'.format(i * 25)
        start_urls.append(url)

    # parse是默認處理response的方法
    def parse(self, response):
        # 使用BeautifulSoup解析response
        bs = bs4.BeautifulSoup(response.text, 'html.parser')
        # 用find_all提取<tr class="item">元素,這個元素裏含有書籍信息。
        datas = bs.find_all('tr', class_='item')

        # 遍歷書籍信息列表
        for data in datas:
            # 實例化BookDoubanItem類
            item = BookDoubanItem()
            # 提取書名,並把這個數據放回BookDoubanItem類的title屬性裏
            item['title'] = data.find_all('a')[1]['title']
            # 提取出版信息,並把這個數據放回BookDoubanItem類的title屬性裏
            item['publish'] = data.find('p',class_='pl').text
            # 提取評分,並把這個數據放回BookDoubanItem類的title屬性裏
            item['score'] = data.find('span',class_='rating_nums').text
            # 打印書名
            print(item['title'])

            # yield item是把獲得的item傳遞給引擎
            yield item

當我們需要記錄一次數據的時候,比如前面在每一個最小循環裏,都要記錄“書名”,“出版信息”,“評分”。我們會實例化一個item對象,利用這個對象來記錄數據。一個對象對應一次數據。

在Scrapy框架裏,每一次當數據完成記錄,它會離開spiders,來到Scrapy Engine(引擎),引擎將它送入Item Pipeline(數據管道)處理。這裏,要用到yield語句。

yield語句可以簡單理解爲:它有點類似return,不過它和return不同的點在於,它不會結束函數,且能多次返回信息。
在這裏插入圖片描述
如果用可視化的方式來呈現程序運行的過程,就如同上圖所示:爬蟲(Spiders)會把豆瓣的10個網址封裝成requests對象,引擎會從爬蟲(Spiders)裏提取出requests對象,再交給調度器(Scheduler),讓調度器把這些requests對象排序處理。

然後引擎再把經過調度器處理的requests對象發給下載器(Downloader),下載器會立馬按照引擎的命令爬取,並把response返回給引擎。

緊接着引擎就會把response發回給爬蟲(Spiders),這時爬蟲會啓動默認的處理response的parse方法,解析和提取出書籍信息的數據,使用item做記錄,返回給引擎。引擎將它送入Item Pipeline(數據管道)處理。

代碼實操——設置

到這裏,我們就用代碼編寫好了一個爬蟲。不過,如果現在就運行的話,可能還是會報錯。

原因在於Scrapy裏的默認設置沒被修改。比如我們需要修改請求頭(User-Agent需要設置)。點擊settings.py文件,你能在裏面找到如下的默認設置代碼:

# Crawl responsibly by identifying yourself (and your website) on the user-agent
#USER_AGENT = 'douban (+http://www.yourdomain.com)'

# Obey robots.txt rules
ROBOTSTXT_OBEY = True

請把USER _AGENT的註釋取消(刪除#),然後替換掉user-agent的內容,就是修改了請求頭。

又因爲Scrapy是遵守robots協議的,如果是robots協議禁止爬取的內容,Scrapy也會默認不去爬取,所以我們還得修改Scrapy中的默認設置。

把ROBOTSTXT_OBEY=True改成ROBOTSTXT_OBEY=False,就是把遵守robots協議換成無需遵從robots協議,這樣Scrapy就能不受限制地運行。

修改後的代碼如下所示:

# Crawl responsibly by identifying yourself (and your website) on the user-agent
USER_AGENT = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.87 Safari/537.36'}

# Obey robots.txt rules
ROBOTSTXT_OBEY = False

現在,我們已經編寫好了spider文件,也修改好了setting文件。最後,我們要來運行整個 scrapy 工程。

代碼實操——運行

想要運行Scrapy有兩種方法:

  • 一種是在本地電腦的終端跳轉到scrapy項目的文件夾(跳轉方法:cd+文件夾的路徑名),然後輸入命令行:scrapy crawl book_douban(book_douban就是我們爬蟲的名字)。
  • 另一種運行方式需要我們在最外層的大文件夾裏新建一個main.py文件(與scrapy.cfg同級)。
# 導入cdmline模塊,可以實現控制終端命令行
from scrapy import cmdline

# 用execute()方法,輸入運行scrapy命令
cmdline.execute(['scrapy', 'crawl', 'book_douban'])

代碼解釋

  • 第1行代碼:在Scrapy中有一個可以控制終端命令的模塊cmdline。導入了這個模塊,我們就能操控終端。

  • 第3行代碼:在cmdline模塊中,有一個execute方法能執行終端的命令行,不過這個方法需要傳入參數。我們輸入運行Scrapy的代碼scrapy crawl book_douban,就需要寫成[‘scrapy’,‘crawl’,‘book_douban’]這樣。

需要注意的是:爲了便於理解和掌握,在這次的內容中,我們是先寫了爬蟲,再定義數據。但是,在我們平常實際做爬蟲項目的時候,順序卻是相反的——先定義數據,再寫爬蟲。所以,流程圖應如下:
在這裏插入圖片描述

三、練習

1.之前的內容中, 我們沒有使用任何框架來爬取豆瓣新片榜。在本次的練習中,我們使用Scrapy來爬取豆瓣新片榜。 地址:https://movie.douban.com/。

實現步驟如下:

1. 創建Scrapy

在命令行中,cd到對應的文件夾路徑

# 打開對應的文件夾路徑
scrapy startproject douban_movie

2. 定義Items

獲取電影標題、導演、評分、簡介信息


import scrapy


class DoubanMovieItem(scrapy.Item):
    title = scrapy.Field()
    director = scrapy.Field()
    score = scrapy.Field()
    info = scrapy.Field()

3. 編寫spiders

在spiders文件夾下方,創建“douban_movie.py"文件,編輯如下代碼

import scrapy
import bs4
from ..items import DoubanMovieItem

# 定義一個爬蟲類Douban_moiveSpider
class Douban_movieSpider(scrapy.Spider):
    # 定義爬蟲的名字
    name = 'douban_movie'
    # 定義爬蟲爬取的網址的域名
    allowed_domains = ['movie.douban.com']
    # 定義起始網址
    start_urls = []
    for i in range(3):
        url = 'https://movie.douban.com/top250?start={}&filter='.format(i*25)
        start_urls.append(url)

    # 定義處理返回數據的類
    def parse(self, response):
        # 使用Beautifulsoup解析response
        bs = bs4.BeautifulSoup(response.text,'html.parser')
        datas = bs.find_all('div',class_='info')

        for data in datas:
            # 實例化DoubanMovieItem類
            item = DoubanMovieItem()
            # 爬下來的電影標題、導演文本中,有“&nbsp”及"\xa0",使用replace替換掉
            item['title'] = data.find('div', class_='hd').find('a').text.replace(u'\xa0','').replace('\n','')
            item['director'] = data.find('p').text.replace(' ', '').replace(u'\xa0','').replace('\n', '')
            # 評分內容有評分和評價人數,中間有換行符和空格,先替換掉空格,再將換行符替換爲空格,後去掉頭尾的空格
            item['score'] = data.find('div', class_='star').text.replace(' ', '').replace('\n', ' ').strip()
            item['info'] = data.find('p', class_='quote').text.replace('\n', '')

            # yield item 把獲得的item傳遞給引擎
            yield item


網頁源代碼中的&nbsp; 的utf-8 編碼是:\xc2\xa0,解析後,轉換爲Unicode字符爲:\xa0,當使用print() 顯示到DOS窗口上的時候,轉換爲GBK編碼的字符串,但是\xa0這個Unicode字符沒有對應的 GBK 編碼的字符串,所以出現錯誤。
解決方法:用空格 來替換 \xa0 (&nbsp;)

  • 方法1:在網頁原碼上替換&nbsp;
soup = BeautifulSoup(html.replace('&nbsp;', ' '), 'html.parser')
  • 方法2:在解析爲Unicode之後替代\xa0
job_detail = soup.select('.job-detail')[0].text.replace(u'\xa0', ' ')

4. 修改settings文件

BOT_NAME = 'douban_movie'

SPIDER_MODULES = ['douban_movie.spiders']
NEWSPIDER_MODULE = 'douban_movie.spiders'


# Crawl responsibly by identifying yourself (and your website) on the user-agent
USER_AGENT = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.87 Safari/537.36'}


# Obey robots.txt rules
ROBOTSTXT_OBEY = False

5. 運行scrapy

  • 在命令行中,cd到項目所在文件夾,運行“scrapy crawl douban_movie"
  • 在與"scray.cfg"文件同級的文件夾中,新建文件"main.py"
# 導入cdmline模塊,可以實現控制終端命令行
from scrapy import cmdline

#用execute()方法,輸入運行scrapy的命令
cmdline.execute(['scrapy','crawl','douban_movie'])
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章