日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

爬虫框架Scrapy的第一个爬虫示例入门教程

發布時間:2025/5/22 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 爬虫框架Scrapy的第一个爬虫示例入门教程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

我們使用dmoz.org這個網站來作為小抓抓一展身手的對象。


首先先要回答一個問題。

問:把網站裝進爬蟲里,總共分幾步?

答案很簡單,四步:

  • 新建項目 (Project):新建一個新的爬蟲項目
  • 明確目標(Items):明確你想要抓取的目標
  • 制作爬蟲(Spider):制作爬蟲開始爬取網頁
  • 存儲內容(Pipeline):設計管道存儲爬取內容


好的,基本流程既然確定了,那接下來就一步一步的完成就可以了。


1.新建項目(Project)

在空目錄下按住Shift鍵右擊,選擇“在此處打開命令窗口”,輸入一下命令:

?

[plain] view plaincopy
  • scrapy?startproject?tutorial??

  • 其中,tutorial為項目名稱。

    可以看到將會創建一個tutorial文件夾,目錄結構如下:

    ?

    [plain] view plaincopy
  • tutorial/??
  • ????scrapy.cfg??
  • ????tutorial/??
  • ????????__init__.py??
  • ????????items.py??
  • ????????pipelines.py??
  • ????????settings.py??
  • ????????spiders/??
  • ????????????__init__.py??
  • ????????????...??



  • 下面來簡單介紹一下各個文件的作用:

    • scrapy.cfg:項目的配置文件
    • tutorial/:項目的Python模塊,將會從這里引用代碼
    • tutorial/items.py:項目的items文件
    • tutorial/pipelines.py:項目的pipelines文件
    • tutorial/settings.py:項目的設置文件
    • tutorial/spiders/:存儲爬蟲的目錄


    2.明確目標(Item)

    在Scrapy中,items是用來加載抓取內容的容器,有點像Python中的Dic,也就是字典,但是提供了一些額外的保護減少錯誤。

    一般來說,item可以用scrapy.item.Item類來創建,并且用scrapy.item.Field對象來定義屬性(可以理解成類似于ORM的映射關系)。

    接下來,我們開始來構建item模型(model)。

    首先,我們想要的內容有:

    • 名稱(name)
    • 鏈接(url)
    • 描述(description)


    修改tutorial目錄下的items.py文件,在原本的class后面添加我們自己的class。

    因為要抓dmoz.org網站的內容,所以我們可以將其命名為DmozItem:

    ?

    [python] view plaincopy
  • #?Define?here?the?models?for?your?scraped?items??
  • #??
  • #?See?documentation?in:??
  • #?http://doc.scrapy.org/en/latest/topics/items.html??
  • ??
  • from?scrapy.item?import?Item,?Field??
  • ??
  • class?TutorialItem(Item):??
  • ????#?define?the?fields?for?your?item?here?like:??
  • ????#?name?=?Field()??
  • ????pass??
  • ??
  • class?DmozItem(Item):??
  • ????title?=?Field()??
  • ????link?=?Field()??
  • ????desc?=?Field()??

  • 剛開始看起來可能會有些看不懂,但是定義這些item能讓你用其他組件的時候知道你的 items到底是什么。

    可以把Item簡單的理解成封裝好的類對象。


    3.制作爬蟲(Spider)

    制作爬蟲,總體分兩步:先爬再取。

    也就是說,首先你要獲取整個網頁的所有內容,然后再取出其中對你有用的部分。

    3.1爬

    Spider是用戶自己編寫的類,用來從一個域(或域組)中抓取信息。

    他們定義了用于下載的URL列表、跟蹤鏈接的方案、解析網頁內容的方式,以此來提取items。

    要建立一個Spider,你必須用scrapy.spider.BaseSpider創建一個子類,并確定三個強制的屬性:

    • name:爬蟲的識別名稱,必須是唯一的,在不同的爬蟲中你必須定義不同的名字。
    • start_urls:爬取的URL列表。爬蟲從這里開始抓取數據,所以,第一次下載的數據將會從這些urls開始。其他子URL將會從這些起始URL中繼承性生成。
    • parse():解析的方法,調用的時候傳入從每一個URL傳回的Response對象作為唯一參數,負責解析并匹配抓取的數據(解析為item),跟蹤更多的URL。

    ?

    這里可以參考寬度爬蟲教程中提及的思想來幫助理解,教程傳送:[Java] 知乎下巴第5集:使用HttpClient工具包和寬度爬蟲。

    也就是把Url存儲下來并依此為起點逐步擴散開去,抓取所有符合條件的網頁Url存儲起來繼續爬取。



    下面我們來寫第一只爬蟲,命名為dmoz_spider.py,保存在tutorial\spiders目錄下。

    dmoz_spider.py代碼如下:

    [python] view plaincopy
  • from?scrapy.spider?import?Spider??
  • ??
  • class?DmozSpider(Spider):??
  • ????name?=?"dmoz"??
  • ????allowed_domains?=?["dmoz.org"]??
  • ????start_urls?=?[??
  • ????????"http://www.dmoz.org/Computers/Programming/Languages/Python/Books/",??
  • ????????"http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/"??
  • ????]??
  • ??
  • ????def?parse(self,?response):??
  • ????????filename?=?response.url.split("/")[-2]??
  • ????????open(filename,?'wb').write(response.body)??
  • allow_domains是搜索的域名范圍,也就是爬蟲的約束區域,規定爬蟲只爬取這個域名下的網頁。

    從parse函數可以看出,將鏈接的最后兩個地址取出作為文件名進行存儲。

    然后運行一下看看,在tutorial目錄下按住shift右擊,在此處打開命令窗口,輸入:

    [plain] view plaincopy
  • scrapy?crawl?dmoz??

  • 運行結果如圖:

    報錯了:

    UnicodeDecodeError: 'ascii' codec can't decode byte 0xb0 in position 1: ordinal?not in range(128)

    運行第一個Scrapy項目就報錯,真是命運多舛。

    應該是出了編碼問題,谷歌了一下找到了解決方案:

    在python的Lib\site-packages文件夾下新建一個sitecustomize.py:

    [python] view plaincopy
  • import?sys????
  • sys.setdefaultencoding('gb2312')????

  • 再次運行,OK,問題解決了,看一下結果:


    最后一句INFO: Closing spider (finished)表明爬蟲已經成功運行并且自行關閉了。

    包含 [dmoz]的行 ,那對應著我們的爬蟲運行的結果。

    可以看到start_urls中定義的每個URL都有日志行。

    還記得我們的start_urls嗎?

    http://www.dmoz.org/Computers/Programming/Languages/Python/Books
    http://www.dmoz.org/Computers/Programming/Languages/Python/Resources

    因為這些URL是起始頁面,所以他們沒有引用(referrers),所以在它們的每行末尾你會看到 (referer: <None>)。

    在parse 方法的作用下,兩個文件被創建:分別是 Books 和 Resources,這兩個文件中有URL的頁面內容。


    那么在剛剛的電閃雷鳴之中到底發生了什么呢?

    首先,Scrapy為爬蟲的 start_urls屬性中的每個URL創建了一個 scrapy.http.Request 對象 ,并將爬蟲的parse 方法指定為回調函數。

    然后,這些 Request被調度并執行,之后通過parse()方法返回scrapy.http.Response對象,并反饋給爬蟲。


    3.2取

    爬取整個網頁完畢,接下來的就是的取過程了。

    光存儲一整個網頁還是不夠用的。

    在基礎的爬蟲里,這一步可以用正則表達式來抓。

    在Scrapy里,使用一種叫做 XPath selectors的機制,它基于 XPath表達式。

    如果你想了解更多selectors和其他機制你可以查閱資料:點我點我


    這是一些XPath表達式的例子和他們的含義

    • /html/head/title: 選擇HTML文檔<head>元素下面的<title> 標簽。
    • /html/head/title/text(): 選擇前面提到的<title> 元素下面的文本內容
    • //td: 選擇所有 <td> 元素
    • //div[@class="mine"]: 選擇所有包含 class="mine" 屬性的div 標簽元素

    以上只是幾個使用XPath的簡單例子,但是實際上XPath非常強大。

    可以參照W3C教程:點我點我。


    為了方便使用XPaths,Scrapy提供XPathSelector 類,有兩種可以選擇,HtmlXPathSelector(HTML數據解析)和XmlXPathSelector(XML數據解析)。

    必須通過一個 Response 對象對他們進行實例化操作。

    你會發現Selector對象展示了文檔的節點結構。因此,第一個實例化的selector必與根節點或者是整個目錄有關 。

    在Scrapy里面,Selectors 有四種基礎的方法(點擊查看API文檔):

    • xpath():返回一系列的selectors,每一個select表示一個xpath參數表達式選擇的節點
    • css():返回一系列的selectors,每一個select表示一個css參數表達式選擇的節點
    • extract():返回一個unicode字符串,為選中的數據
    • re():返回一串一個unicode字符串,為使用正則表達式抓取出來的內容


    3.3xpath實驗

    下面我們在Shell里面嘗試一下Selector的用法。

    實驗的網址:http://www.dmoz.org/Computers/Programming/Languages/Python/Books/



    熟悉完了實驗的小白鼠,接下來就是用Shell爬取網頁了。

    進入到項目的頂層目錄,也就是第一層tutorial文件夾下,在cmd中輸入:

    ?

    [plain] view plaincopy
  • scrapy?shell?http://www.dmoz.org/Computers/Programming/Languages/Python/Books/??

  • 回車后可以看到如下的內容:

    ?


    在Shell載入后,你將獲得response回應,存儲在本地變量 response中。

    所以如果你輸入response.body,你將會看到response的body部分,也就是抓取到的頁面內容:


    或者輸入response.headers 來查看它的 header部分:



    現在就像是一大堆沙子握在手里,里面藏著我們想要的金子,所以下一步,就是用篩子搖兩下,把雜質出去,選出關鍵的內容。

    selector就是這樣一個篩子。

    在舊的版本中,Shell實例化兩種selectors,一個是解析HTML的 hxs 變量,一個是解析XML 的 xxs 變量。

    而現在的Shell為我們準備好的selector對象,sel,可以根據返回的數據類型自動選擇最佳的解析方案(XML or HTML)。

    然后我們來搗弄一下!~

    要徹底搞清楚這個問題,首先先要知道,抓到的頁面到底是個什么樣子。

    比如,我們要抓取網頁的標題,也就是<title>這個標簽:


    可以輸入:

    [python] view plaincopy
  • sel.xpath('//title')??

  • 結果就是:


    這樣就能把這個標簽取出來了,用extract()和text()還可以進一步做處理。

    備注:簡單的羅列一下有用的xpath路徑表達式:

    ?

    表達式描述
    nodename選取此節點的所有子節點。
    /從根節點選取。
    //從匹配選擇的當前節點選擇文檔中的節點,而不考慮它們的位置。
    .選取當前節點。
    ..選取當前節點的父節點。
    @選取屬性。


    全部的實驗結果如下,In[i]表示第i次實驗的輸入,Out[i]表示第i次結果的輸出(建議大家參照:W3C教程):

    [python] view plaincopy
  • In?[1]:?sel.xpath('//title')??
  • Out[1]:?[<Selector?xpath='//title'?data=u'<title>Open?Directory?-?Computers:?Progr'>]??
  • ??
  • In?[2]:?sel.xpath('//title').extract()??
  • Out[2]:?[u'<title>Open?Directory?-?Computers:?Programming:?Languages:?Python:?Books</title>']??
  • ??
  • In?[3]:?sel.xpath('//title/text()')??
  • Out[3]:?[<Selector?xpath='//title/text()'?data=u'Open?Directory?-?Computers:?Programming:'>]??
  • ??
  • In?[4]:?sel.xpath('//title/text()').extract()??
  • Out[4]:?[u'Open?Directory?-?Computers:?Programming:?Languages:?Python:?Books']??
  • ??
  • In?[5]:?sel.xpath('//title/text()').re('(\w+):')??
  • Out[5]:?[u'Computers',?u'Programming',?u'Languages',?u'Python']??


  • 當然title這個標簽對我們來說沒有太多的價值,下面我們就來真正抓取一些有意義的東西。

    使用火狐的審查元素我們可以清楚地看到,我們需要的東西如下:



    我們可以用如下代碼來抓取這個<li>標簽:

    ?

    [python] view plaincopy
  • sel.xpath('//ul/li')??
  • 從<li>標簽中,可以這樣獲取網站的描述:

    [python] view plaincopy
  • sel.xpath('//ul/li/text()').extract()??



  • 可以這樣獲取網站的標題:

    [python] view plaincopy
  • sel.xpath('//ul/li/a/text()').extract()??

  • 可以這樣獲取網站的超鏈接:

    [python] view plaincopy
  • sel.xpath('//ul/li/a/@href').extract()??

  • 當然,前面的這些例子是直接獲取屬性的方法。

    我們注意到xpath返回了一個對象列表,

    那么我們也可以直接調用這個列表中對象的屬性挖掘更深的節點

    (參考:Nesting selectors andWorking with relative XPaths in the Selectors):

    ?

    sites = sel.xpath('//ul/li') for site in sites: title = site.xpath('a/text()').extract() link = site.xpath('a/@href').extract() desc = site.xpath('text()').extract() print title, link, desc

    ?

    3.4xpath實戰

    我們用shell做了這么久的實戰,最后我們可以把前面學習到的內容應用到dmoz_spider這個爬蟲中。

    在原爬蟲的parse函數中做如下修改:

    ?

    [python] view plaincopy
  • from?scrapy.spider?import?Spider??
  • from?scrapy.selector?import?Selector??
  • ??
  • class?DmozSpider(Spider):??
  • ????name?=?"dmoz"??
  • ????allowed_domains?=?["dmoz.org"]??
  • ????start_urls?=?[??
  • ????????"http://www.dmoz.org/Computers/Programming/Languages/Python/Books/",??
  • ????????"http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/"??
  • ????]??
  • ??
  • ????def?parse(self,?response):??
  • ????????sel?=?Selector(response)??
  • ????????sites?=?sel.xpath('//ul/li')??
  • ????????for?site?in?sites:??
  • ????????????title?=?site.xpath('a/text()').extract()??
  • ????????????link?=?site.xpath('a/@href').extract()??
  • ????????????desc?=?site.xpath('text()').extract()??
  • ????????????print?title??

  • 注意,我們從scrapy.selector中導入了Selector類,并且實例化了一個新的Selector對象。這樣我們就可以像Shell中一樣操作xpath了。

    我們來試著輸入一下命令運行爬蟲(在tutorial根目錄里面):

    scrapy crawl dmoz

    ?

    運行結果如下:

    果然,成功的抓到了所有的標題。但是好像不太對啊,怎么Top,Python這種導航欄也抓取出來了呢?

    我們只需要紅圈中的內容:


    看來是我們的xpath語句有點問題,沒有僅僅把我們需要的項目名稱抓取出來,也抓了一些無辜的但是xpath語法相同的元素。

    審查元素我們發現我們需要的<ul>具有class='directory-url'的屬性,

    那么只要把xpath語句改成sel.xpath('//ul[@class="directory-url"]/li')即可

    將xpath語句做如下調整:

    [python] view plaincopy
  • from?scrapy.spider?import?Spider??
  • from?scrapy.selector?import?Selector??
  • ??
  • class?DmozSpider(Spider):??
  • ????name?=?"dmoz"??
  • ????allowed_domains?=?["dmoz.org"]??
  • ????start_urls?=?[??
  • ????????"http://www.dmoz.org/Computers/Programming/Languages/Python/Books/",??
  • ????????"http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/"??
  • ????]??
  • ??
  • ????def?parse(self,?response):??
  • ????????sel?=?Selector(response)??
  • ????????sites?=?sel.xpath('//ul[@class="directory-url"]/li')??
  • ????????for?site?in?sites:??
  • ????????????title?=?site.xpath('a/text()').extract()??
  • ????????????link?=?site.xpath('a/@href').extract()??
  • ????????????desc?=?site.xpath('text()').extract()??
  • ????????????print?title??

  • 成功抓出了所有的標題,絕對沒有濫殺無辜:


    3.5使用Item

    接下來我們來看一看如何使用Item。

    前面我們說過,Item 對象是自定義的python字典,可以使用標準字典語法獲取某個屬性的值:

    [python] view plaincopy
  • >>>?item?=?DmozItem()??
  • >>>?item['title']?=?'Example?title'??
  • >>>?item['title']??
  • 'Example?title'??

  • 作為一只爬蟲,Spiders希望能將其抓取的數據存放到Item對象中。為了返回我們抓取數據,spider的最終代碼應當是這樣:

    ?

    [python] view plaincopy
  • from?scrapy.spider?import?Spider??
  • from?scrapy.selector?import?Selector??
  • ??
  • from?tutorial.items?import?DmozItem??
  • ??
  • class?DmozSpider(Spider):??
  • ????name?=?"dmoz"??
  • ????allowed_domains?=?["dmoz.org"]??
  • ????start_urls?=?[??
  • ????????"http://www.dmoz.org/Computers/Programming/Languages/Python/Books/",??
  • ????????"http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/"??
  • ????]??
  • ??
  • ????def?parse(self,?response):??
  • ????????sel?=?Selector(response)??
  • ????????sites?=?sel.xpath('//ul[@class="directory-url"]/li')??
  • ????????items?=?[]??
  • ????????for?site?in?sites:??
  • ????????????item?=?DmozItem()??
  • ????????????item['title']?=?site.xpath('a/text()').extract()??
  • ????????????item['link']?=?site.xpath('a/@href').extract()??
  • ????????????item['desc']?=?site.xpath('text()').extract()??
  • ????????????items.append(item)??
  • ????????return?items??


  • 4.存儲內容(Pipeline)

    保存信息的最簡單的方法是通過Feed exports,主要有四種:JSON,JSON lines,CSV,XML。

    我們將結果用最常用的JSON導出,命令如下:


    [plain] view plaincopy
  • scrapy?crawl?dmoz?-o?items.json?-t?json??

  • -o 后面是導出文件名,-t 后面是導出類型。

    然后來看一下導出的結果,用文本編輯器打開json文件即可(為了方便顯示,在item中刪去了除了title之外的屬性):




    因為這個只是一個小型的例子,所以這樣簡單的處理就可以了。

    如果你想用抓取的items做更復雜的事情,你可以寫一個 Item Pipeline(條目管道)。

    這個我們以后再慢慢玩^_^

    轉載于:https://www.cnblogs.com/wuxl360/p/5567631.html

    總結

    以上是生活随笔為你收集整理的爬虫框架Scrapy的第一个爬虫示例入门教程的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。