python爬蟲入門筆記:scrapy爬豆瓣


把網站裝進爬蟲里,分為幾步:

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

1.新建項目(Project)

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

>scrapy startproject douban

創建project完成后,生成如下目錄:

用pycharm打開該項目,具體看一下:

各個文件的作用:

    • scrapy.cfg:項目的配置文件
    • douban/:項目的Python模塊,將會從這里引用代碼
    • douban/items.py:項目的items文件(items是用來加載抓取內容的容器)
    • douban/pipelines.py:項目的pipelines文件
    • douban/settings.py:項目的設置文件
    • douban/spiders/:存儲爬蟲的目錄     

2.明確目標(Item) 

item可以用scrapy.item.Item類來創建,並且用scrapy.item.Field對象來定義屬性。

接下來,我們開始來構建item模型(model)。本例中,構建items.py如下:

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

  • 電影名稱(name)
  • 電影描述(movieInfo)
  • 電影評分(star)
  • 格言(quote)
  • 對應地,修改douban目錄下的items.py文件,在原本的class后面添加我們自己的class。因為要抓豆瓣網站的內容,所以我們可以將其命名為DoubanItem:

【attention】:

爬取元素並不是必須聲明一個model,也可以直接在爬蟲代碼中,將爬取的元素直接通過這種方式來展現


根據官方文檔介紹,Item是保存結構數據的地方,Scrapy可以將解析結果以字典形式返回,但是Python中字典缺少結構,在大型爬蟲系統中很不方便,Item提供了類字典的API,並且可以很方便的聲明字段,很多Scrapy組件可以利用Item的其他信息。后面也可以方便pipelines對爬到的數據進行處理。

 

3.制作爬蟲(Spider)

制作爬蟲,總體分兩步:爬——取

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

3.1爬

Spider是用戶自己編寫的類,用來從一個域(或域組)中抓取信息。定義了用於下載的URL列表跟蹤鏈接的方案、解析網頁內容的方式,以此來提取items。

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

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

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

在douban目錄下按住shift右擊,在此處打開命令窗口,輸入:

 >scrapy crawl douban

 

3.1.1 創建main.py,保存在douban目錄下

3.1.2 為免於被封,需要偽裝一下,在settings.py里加上USER_AGENT

USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_3) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.54 Safari/536.5'   

 

3.2取

使用Xpath來解析,相關知識可以看 Xpath那一節,這里不細說,只是講一下大概思路:
F12審查元素,我們看一下頁面代碼,查看頁面顯示特征,如待抓取的頁面內容是否需要組合,替換空格等,同時,存在分頁情形要能自動抓取下一頁
查看代碼特征后,發現幾個問題:
(1) title分在兩行,需要用for循環遍歷的方式把它組合起來;
(2) 部分電影沒有quote,需要考慮為空值情況;
(3) 分頁的url不完整,需要把它抓出來補成完整的URL(要引入 Request, from scrapy.http import Request
),就可以循環抓取了。

  1. # -*- coding: utf-8 -*-  
  2.   
  3. from scrapy.spiders import CrawlSpider  
  4. from scrapy.selector import Selector  
  5. from douban.items import DoubanItem  
  6. from scrapy.http import Request  
  7.   
  8. class Douban(CrawlSpider):  
  9.     name = "douban"  
  10.     start_urls = ['http://movie.douban.com/top250']  
  11.   
  12.     url = 'http://movie.douban.com/top250'  
  13.   
  14.     def parse(self,response):  
  15.         #print response.body  
  16.         item = DoubanItem()  
  17.         selector = Selector(response)  
  18.         #print selector  
  19.         Movies = selector.xpath('//div[@class="info"]')  
  20.         #print Movies  
  21.         for eachMoive in Movies:  
  22.             title = eachMoive.xpath('div[@class="hd"]/a/span/text()').extract()  
  23.             # 把兩個名稱合起來  
  24.             fullTitle = ''  
  25.             for each in title:  
  26.                 fullTitle += each  
  27.             movieInfo = eachMoive.xpath('div[@class="bd"]/p/text()').extract()  
  28.             star = eachMoive.xpath('div[@class="bd"]/div[@class="star"]/span[@class="rating_num"]/text()').extract()[0]  
  29.             quote = eachMoive.xpath('div[@class="bd"]/p[@class="quote"]/span/text()').extract()  
  30.             # quote可能為空,因此需要先進行判斷  
  31.             if quote:  
  32.                 quote = quote[0]  
  33.             else:  
  34.                 quote = ''  
  35.             #print fullTitle  
  36.             #print movieInfo  
  37.             #print star  
  38.             #print quote  
  39.             item['title'] = fullTitle  
  40.             item['movieInfo'] = ';'.join(movieInfo)  
  41.             item['star'] = star  
  42.             item['quote'] = quote  
  43.             yield item  
  44.             nextLink = selector.xpath('//span[@class="next"]/link/@href').extract()  
  45.             # 第10頁是最后一頁,沒有下一頁的鏈接  
  46.             if nextLink:  
  47.                 nextLink = nextLink[0]  
  48.                 print nextLink  
  49.                 yield Request(self.url + nextLink, callback=self.parse)    ## 遞歸將下一頁的地址傳給這個函數自己,在進行爬取注意寒老師提供的栗子中對此處二次解析的解讀 callback=self.parse

4.存儲內容(Pipeline)

保存信息的最簡單的方法是通過Feed exports,主要有四種:JSON,JSON lines,CSV,XML。將結果用最常用的JSON導出,命令如下:

>scrapy crawl douban -o items.json -t json        #-o 后面是導出文件名,-t 后面是導出類型。導出的結果,用文本編輯器打開json文件即可

嘗試導出csv格式:

>scrapy crawl douban -o items.csv -t csv

4.1 設置默認存儲

可以直接在settings.py文件中設置輸出的位置和文件類型,如下:

  1. FEED_URI = u'file:///E:/douban/douban.csv'  
  2. FEED_FORMAT = 'CSV'  

 

5.運行爬蟲(main.py)

不同於簡單單線程爬蟲程序直接運行,這里我們還需要通過一個main.py來運行,需要自己手動生成,main.py代碼如下:

運行結果:

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

 

 


免責聲明!

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



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