1. 程式人生 > >Scrapy 爬蟲 --四個步驟--

Scrapy 爬蟲 --四個步驟--

課程設計要用到爬蟲,稍微回顧下,Scrapy的爬蟲四步走....只是簡單的Scrapy,什麼分散式爬蟲啥的,感覺以後再說了....不談了...

1、建立專案

cmd >> scrapy  startproject  douban## scrapy  startproject  project_name 

cmd >> cd  douban/douban/spiders

cmd >> scrapy  genspider  douban_spider  movie.douban.com## scrapy  genspider  spider_text_name  start_url


Scrapy包含上圖幾個部件:

1、Scrapy Engine

引擎負責控制資料流在系統中所有元件中流動,並在相應動作發生時觸發事件。 

2、Scheduler

排程器從引擎接受request並將他們入隊,以便之後引擎請求他們時提供給引擎;簡單的說就是排程佇列,same as 作業系統中的排程佇列.......

3、Downloader

下載器負責獲取頁面資料並提供給引擎,而後提供給spider。

4、Spiders

Spider是Scrapy使用者編寫用於分析response提取item(即獲取到的item)或額外跟進的URL的類。 每個spider負責處理一個特定(或一些)網站。

5、Item Pipeline

Item Pipeline負責處理被spider提取出來的item。典型的處理有清理、 驗證及持久化(例如存取到資料庫中)。

6、Downloader middlewares

下載器中介軟體是在引擎及下載器之間的specific hook,處理Downloader傳遞給引擎的response。 其提供了一個簡便的機制,通過插入自定義程式碼來擴充套件Scrapy功能。

7、Spider middlewares

Spider中介軟體是在引擎及Spider之間的specific hook,處理spider的輸入(response)和輸出(items及requests)。 其提供了一個簡便的機制,通過插入自定義程式碼來擴充套件Scrapy功能。


 

  • scrapy.cfg: 專案的配置檔案;
  • project_modul/: 該專案的python模組。之後您將在此加入程式碼;
  • project_modul/items.py: 專案中的item檔案;
  • project_modul/pipelines.py: 專案中的pipelines檔案;
  • project_modul/settings.py: 專案的設定檔案;
  • project_modul/spiders/: 放置spider程式碼的目錄;

 

2、明確目標

即瞭解你要哪些資料 ——>>> item.py

class DoubanItem(scrapy.Item):
         #序號
         serial_number = scrapy.Field()
         #電影名稱
         movie_name = scrapy.Field()
         #介紹
         introduce = scrapy.Field()
         #星級
         star = scrapy.Field()
         #描述
         describe = scrapy.Field()

熟悉Django的朋友一定會注意到Scrapy Item定義方式與Django Models很類似, 不過沒有那麼多不同的欄位型別(Field type),更為簡單。

 

3、爬蟲檔案的編寫 ——>>> spiders [folders]

Spider類定義瞭如何爬取某個(或某些)網站。包括了爬取的動作以及如何從網頁的內容中提取結構化資料(爬取item)。 換句話說,Spider就是您定義爬取的動作及分析某個網頁(或者是有些網頁)的地方。

能夠獲取兩類資料,一種就是純資料,比如Title啥的,另外一種資料就是可遞迴的資料,即資料多的時候有好幾頁資料,裡面的第二頁,第幾頁就是可遞迴的連結資料

  1. 以初始的URL初始化Request,並設定回撥函式。 當該request下載完畢並返回時,將生成response,並作為引數傳給該回調函式。

    spider中初始的request是通過呼叫 start_requests() 來獲取的。 start_requests() 讀取 start_url中的URL, 並以 Parse 為回撥函式生成Request 。

  2. 在回撥函式內分析返回的(網頁)內容,返回 Item 物件或者Request或者一個包括二者的可迭代容器。 返回的Request物件之後會經過Scrapy處理,下載相應的內容,並呼叫設定的callback函式(函式可相同)。

  3. 在回撥函式內,您可以使用選擇器(Selectors) (您也可以使用BeautifulSoup, lxml 或者您想用的任何解析器) 來分析網頁內容,並根據分析的資料生成item。

         最後,由spider返回的item將被存到資料庫(由某些Item Pipeline處理)或使用Feed exports存入到檔案中。


class DoubanSpiderSpider(scrapy.Spider):
         #爬蟲名 #與專案名不同
         name = 'douban_spider'  
         #域名 #不在這個域名下不解析
         allowed_domains = ['movie.douban.com'] 
         #入口url,並將入口URL 扔進排程器【Schedule】中
         start_urls = ['https://movie.douban.com/top250'] 
         #扔進排程器【Schedule】之後,Schedule 告訴爬蟲引擎自己準備好了,然後爬蟲引擎讓Downloader去下載數                 據,獲取頁面
         #然後將獲取的頁面返回值Spider檔案中,讓Spider進行解析,那如何解析檔案就是下面的parse方法,這個                       response就是Downloader的返回值,可以詳細見上面的那張圖
         def parse(self, response):
                   print(response.text)


cmd >> scrapy crawl spider_name


可能遇見錯誤一:編碼問題

import sys,io
sys.stdout = io.TextIOWrapper(sys.stdout.buffer,encoding='gb18030')

可能遇見錯誤二:不給解析

USER_AGENT = 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Mobile Safari/537.36' #網站上自己看USER_AGENT


爬取第一類資料:純資料

class DoubanSpiderSpider(scrapy.Spider):
         #爬蟲名 #與專案名不同
         name = 'douban_spider'  
         #域名 #不在這個域名下不解析
         allowed_domains = ['movie.douban.com'] 
         #入口url,並將入口URL 扔進排程器【Schedule】中
         start_urls = ['https://movie.douban.com/top250'] 
         #扔進排程器【Schedule】之後,Schedule 告訴爬蟲引擎自己準備好了,然後爬蟲引擎讓Downloader去下載資料,             獲取頁面
         #然後將獲取的頁面返回值Spider檔案中,讓Spider進行解析,那如何解析檔案就是下面的parse方法,這個response           就是Downloader
         #的返回值,可以詳細見上面的那張圖
         def parse(self, response):
                movie_list=response.xpath("//div[@class='article']//ol[@class='grid_view']//li")
                for i in movie_list:
                       Douban_item=DoubanItem()      ##匯入item包,你要存到item中
                       Douban_item['serial_number']=i.xpath(".//div[@class='item']//em/text()").extract_first()  #獲取第一個資料  
                       #如果有多個數據,你想把資料拼接起來
                       #content=i.xpath(...).extract()
                       #for ii in content:
                       #      c_s="".join(ii.split())
                       #            =
                      print(Douban_item)
                      #將資料返回至pipe中,請仔細看scrapy的流程圖就知道了,不加yield不行
                      yield Douban_item


爬取第二類資料:下頁資料 

      next_link = response.xpath("//span[@class='next']/link/@href").extract()
        if next_link:
                     next_link=next_link[0]
                     yield scrapy.Request("https://movie.douban.com/top250"+next_link,callback=self.parse)

 

4、儲存內容

將爬取的資料匯出json檔案,csv檔案

cmd >> scrapy  crawl  spider_name -o _name.json

cmd >> scrapy  crawl  spider_name -o _name.csv

儲存檔案至資料庫


---settings.py---  # 先寫資料庫配置檔案

MYSQL_HOST = 'localhost'

MYSQL_DBNAME = 'scrapy'

MYSQL_USER = 'root'

MYSQL_PASSWD = ''

MYSQL_PORT = 3306


---pipelines.py---  # 傳入資料

import pymysql  ##匯入python中的mysql包,pymysql

from project.settings import MYSQL_HOST,MYSQL_DBNAME,MYSQL_USER,MYSQL_PASSWD,MYSQL_PORT

class DoubanPipeline(object):

       def process_item(self, item, spider):
                 # open db
                 self.connect = pymysql.connect(
                         host=MYSQL_HOST,port=MYSQL_PORT,user=MYSQL_USER,db=MYSQL_DBNAME,
                         passwd=MYSQL_PASSWD,charset='utf8',use_unicode=True)
                 self.cursor = self.connect.cursor()
                 # insert db
                 num = item['serial_number']
                 sql = 'insert into test(num) values("%s")' % (num)
                 self.cursor.execute(sql)
                 self.connect.commit()
                 # close db
                 self.cursor.close()
                 self.connect.close()
                 return item


---settings.py---   #開啟管道 ITEM_PIPELINES ,取消下面這個註釋

ITEM_PIPELINES = {
   'douban.pipelines.DoubanPipeline': 300,
}