scrapy爬蟲筆記(三)------寫入源文件的爬取


開始爬取網頁:(2)寫入源文件的爬取

  為了使代碼易於修改,更清晰高效的爬取網頁,我們將代碼寫入源文件進行爬取。

  主要分為以下幾個步驟:

    一.使用scrapy創建爬蟲框架:

    二.修改並編寫源代碼,確定我們要爬取的網頁及內容

    三.開始爬取並存入文件(數據庫)

注:為了避免冗長的敘述,更直觀地理解,這里先講具體的操作方法,如果想要深入理解其原理,具體解釋在最后。

 

*操作方法:

  1.創建爬蟲框架

  打開命令行,使用cd命令,進入你想要創建文件的位置

  scrapy startproject 文件夾名稱(假設為demo

    scrapy startproject demo

  強大的scrapy會在當前路徑下自動生成爬蟲框架如下:demo/

   scrapy.cfg #項目配置文件
   demo/
   __init__.py
   items.py           #設定數據存入的對象
   pipelines.py         #與數據庫交互
   settings.py #爬蟲配置文件
   spiders/
    __init__.py
  2.編輯源代碼,確定爬取方案
  scrapy不僅僅幫助我們生成好了框架,還提供了很多內置的方法供我們使用,我們只需要利用這些方法並結合BeautifulSoup庫
進行網頁信息的篩選。

  開始寫代碼吧!
  首先打開items.py文件,修改如下:
 1 # -*- coding: utf-8 -*-
 2 
 3 # Define here the models for your scraped items
 4 #  5 # See documentation in:
 6 # http://doc.scrapy.org/en/latest/topics/items.html
 7 
 8 import scrapy  9 
10 
11 class DemoItem(scrapy.Item): 12     # define the fields for your item here like:
13     name = scrapy.Field() 14     #pass

  然后在spider目錄下新建spider.py,將下述代碼復制到其中
 1 # -*- coding: utf-8 -*-
 2 import scrapy
 3 from bs4 import BeautifulSoup
 4 from demo.items import DemoItem
 5 
 6 class demo(scrapy.Spider):
 7     name = "demo"
 8     start_urls = ['http://www.cnblogs.com/KoalaDream/']
 9 
10     def parse(self, response):
11         soup = BeautifulSoup(response.body)
12         tmp=soup.find_all('div',attrs={'class':'postTitle'})
13         for i in range(0,len(tmp)):
14             item=DemoItem()
15             item['name']=tmp[i].text.encode('utf-8')
16             yield item
 
        

  這段代碼的作用是爬取我的博客主頁的文章標題,具體語句的作用在后面有介紹。

  3.開始爬取並存入文件

    代碼編寫好了,我們要開始爬取網頁了,是不是很容易?

    在命令行中,使用cd命令進入scrapy.cfg所在的目錄

      scrapy crawl demo -o output.json

    開始爬取,並將內容輸出到含有scrapy.cfg文件的目錄下output.json文件中 

  完成!

 

  打開output.json文件,什么?怎么全是亂碼?

  這是因為我們爬取下的中文字符,以unicode的編碼格式存儲在文件中。

  想要看到中文字符,可以將輸出的內容復制,打開python,輸入print u"---"將復制的unicode碼粘貼,便可輸出對應的中文字符。

 

*代碼詳解 

  首先,設置編碼格式為utf-8,能夠顯示中文注釋。

  在spider中,scrapy框架規定其中有三個必需的定義的成員。

    name: 名字,spider的標識,我們爬取時在命令行中輸入的 scrapy crawl ____ 即為此處定義的name

    start_urls:一個url列表,spider從這些網頁開始抓取

    parse():一個方法,當start_urls里面的網頁抓取下來之后scrapy會自動調用這個方法解析網頁內容。

  總的來說就是name告訴scrapy框架,我要運行哪個框架。然后scrapy會運行該框架,自動鏈接到start_url的web頁面,生成response對象,將爬取下源代碼存入response對象里面。

 

  下面我們來看具體的parse()方法是如何工作的。

  首先引入BeautifulSoup庫,它可以大大簡化我們的爬取過程。

  然后我們打開要爬取的網頁即 http://www.cnblogs.com/KoalaDream/

  查看源代碼。(chrome瀏覽器中,鼠標右鍵點擊某一個文章標題,點擊審查元素)

  可以看到,每一個標題都是在一個<div>標簽里面,class屬性均為postTitle

  於是,我們使用BeautifulSoup中提供的方法篩選出標題

    tmp=soup.find_all('div',attrs={'class':'postTitle'})

  將標題以列表的形式存入tmp中。

 

  還記得我們剛剛修改過的items.py文件嗎?

  下面我們要遍歷tmp中的每一項,並將其存入剛剛定義過的item中。

  通過 item=DemoItem(),創建了一個DemoItem類的對象,下面的操作

    item['name']=tmp[i].text.encode('utf-8')

  左側的運算符有些讓人費解。因為想要操作類中的成員,一般使用item.name,這個操作符是怎么回事呢?

  仔細觀察items.py文件中,DemoItem類繼承了scrapy.Item類。經試驗證明,如果把繼承去除,此運算符不再存在。

  說明在scrapy.Item類中,對運算符[]進行了重載。個人感覺意義上和.操作符沒什么區別,我們直接使用此語法即可。

 

  最后就是 yield item了

  yield語法查了很久,已經被生成器,迭代器搞得有些暈。

  如果想了解具體的yield語法,請看下面的鏈接  

  http://www.oschina.net/translate/improve-your-python-yield-and-generators-explained

  對於這里的yield語句的作用,我說說我的理解,哪里不准確希望大家多多指教。

  首先簡單介紹下yield語句:

  yield用於函數,就像return,給函數一個返回值。不同的是,return標志着函數結束,而yield是讓函數暫停,直到這個函數再次被調用,會從暫停的地方繼續執行,而不是從頭開始。

  在spider.py的代碼中,每循環一次,yield語句將列表中當前的值返回給parse。可是我們並沒有主動調用和返回。那么輸出的內容是哪里來的?

  因為parse是在scrapy框架中,自動被調用的方法,我們可以推測出:

  當告訴scrapy輸出到output.json文件中時,對於每一次yield的返回值,會被自動print到output.json文件中。然后scrapy會再次調用parse方法,從剛剛間斷的位置,即for循環的下一個列表項開始。如此循環,直到函數結束。這樣一來,tmp中的內容就被存放到item['name']中,然后被輸出到output.json中。

 

  每一次yield返回的一個值就是所謂的生成器。

  而每一次從暫停狀態,再被調用時,自動從暫停前的下一個對象開始,就是所謂的迭代器。

 

  附:官方文檔

    Scrapy  http://doc.scrapy.org/en/latest/

 


免責聲明!

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



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