Scrapy爬蟲框架的介紹,實戰

                                                Scrapy介紹

Scrapy是什麼?

Scrapy是一套基於Twisted的異步處理框架,是純python實現的爬蟲框架,用戶只需要定製開發幾個模塊就可以輕鬆的實現一個爬蟲,用來抓取網頁內容或者各種圖片。

Scrapy框架

Scrapy Engine:Scrapy引擎相當於一箇中樞站,負責Scheduler,Item Pipeline,Downloader和Spiders四個組件之間的通信。例如,將接收到的Spiders的Requests發送給Scheduler,將Spiders的存儲請求發送給Item Pipeline。Scheduler發送的Requests,會被引擎提交到Downloader處理,而Downloader處理完成後會發送Responses給引擎,引擎將其發送至Spiders進行處理。

Spiders:相當於一個解析器,負責接收Scrapy Engine發送過來的Responses,對其進行解析,你可以在其內部編寫解析的規則。解析好的內容可以發送存儲請求給Scrapy Engine。在Spiders中解析出的新的url,可以向Scrapy Engine發送Requests請求。注意,入口url也是存儲在Spiders中。

Downloader:下載器即對發送過來的url進行下載,並將下載好的網頁反饋給Scrapy Engine。

Schedular:你可以把他理解成一個對列,存儲Scrapy Engine發送過來的url,並按順序取出url發送給Scrapy Engine進行requests操作。

Item Pipeline:在Item中你可以定義你的存儲結構,方便數據存儲。而在Pipeline中,你可以對數據進行存儲操作,例如將數據存儲至數據庫,或者以csv格式存貯本地。

Downloader Middlewares:你可以在其中對ip進行代理,或封裝自己的頭文件,應對一些反爬蟲機制。

Spider Middlewares:你可以添加代碼來處理髮送給 Spiders 的 response 及 spider 產生的 item 和 request。

創建scrapy爬蟲項目

第一步,我們先來創建一個scrapy的爬蟲項目。打開cmd,來到要創建的目錄中輸入以下命令。

創建成功後,將項目導入至PyCharm中

先來看配置文件scrapy.cfg。

setting.py文件中可以進行爬蟲配置的設置

其它設置在以後開發項目中需要時再進行介紹,這裏就不一一贅述(其實我也不太清楚,但不着急,慢慢來)

 

Item.py文件是用來定義存儲結構的地方。

 

所以編寫解析規則的spider文件在哪?是的,確實沒找到,這裏我們要用命令行生成spider文件,來到項目目錄,輸入一下命令。

這時我們就可以看到目錄中已經生成了movie_spider.py文件,現在我們就可以在這裏寫解析規則了。

其它的我也不多做贅述,在下面的爬蟲實戰中會再詳細說明。

 

                                                Scrapy實戰

目標

爬取豆瓣電影top250的所有電影信息,將信息存儲至數據庫。

分析

打開網頁https://movie.douban.com/top250,分析我們要爬取的內容。

我們需要抓取電影的排名、名字、出品年份等信息。先在Item.py中定義數據結構。

再來分析一下網頁源碼,通過XPath規則定位到電影信息標籤

 

現在我們就開始爬蟲

我們現在先編寫spider文件

 def parse(self, response):
        #爬取電影item
        movie_item=response.xpath("//div[@class='article']/ol/li")
        for item in movie_item:
            #創建存儲對象
            movieItem=MoviespiderItem()
            #爬取電影信息
            #電影序號
            movieItem['serial_number']=item.xpath(".//div/div/em/text()").extract_first()
            #電影名稱
            movieItem['film_name'] = item.xpath(".//div/div/div/a/span[@class='title']/text()").extract_first()
            #電影的年份 製作人等信息
            info_item=item.xpath(".//div/div/div[@class='bd']/p[1]/text()").extract()
            #電影製作人
            movieItem['film_maker']="".join(info_item[0].split())
            #電影年份
            movieItem['film_time'] =(''.join(info_item[1].split())).split('/')[0]
            #電影出品國家
            movieItem['film_country'] = (''.join(info_item[1].split())).split('/')[1]
            #電影類型
            movieItem['film_type'] = (''.join(info_item[1].split())).split('/')[2]
            #電影引用
            movieItem['film_quote'] = item.xpath(".//div/div/div[@class='bd']/p[2]/span/text()").extract_first()
            #電影評分
            movieItem['film_score'] = item.xpath(".//div/div/div[@class='bd']/div/span[@class='rating_num']/text()").extract_first()
            #將數據傳到pipeline
            yield movieItem
        #解析下一頁url
        next_page=response.xpath("//div[@class='paginator']/span[@class='next']/link/@href").extract()
        #判斷是否有下一頁
        if next_page:
            next_page=next_page[0]
            url=self.start_urls[0]+next_page
            #將下一頁url傳給調度器
            yield scrapy.Request(url,callback=self.parse)

我們來運行一下,是否能夠爬取到我們所需要的內容。在cmd命令行中輸入命令

E:\code\Python\python spider\movieSpider>scrapy crawl movieSpider

爬取結果

可以看到我們已經爬取到了需要的內容。不過有一點需要注意,爬取前要在setting.py中設置User-Agent

既然爬取到內容,就要對內容進行存儲,先來說如何存儲到本地。以csv文件存至本地只需要輸入以下命令

E:\code\Python\python spider\movieSpider>scrapy crawl movie_spider -o movie_list.csv

運行後我們可以來到爬蟲目錄中查看到我們保存的csv文件

相對於保存至本地,將我們的爬蟲項目保存至數據庫中,更方便我們對數據進行操作,也更適應企業要求。這裏我使用的是mysql數據庫,我們需要先創建數據庫,在創建存貯內容的表,這一過程我就略過了,現在主要講我們如何連接數據庫,並將內容進行保存。首先我們要明確一點,我們在Scrapy項目的哪一組件進行這一操作,在文章的開頭已經描述過,Pipeline組件是用來進行數據存儲的。我們先來setting文件中設置我們的mysql參數,這樣也更方便今後的操作,也更有邏輯性。

再來我們就可以在Pipeline中進行存儲操作了

# -*- coding: utf-8 -*-
import pymysql
from movieSpider.settings import table_name,mysql_port,mysql_db,mysql_passwd,mysql_user,mysql_host

class MoviespiderPipeline(object):
    def __init__(self):
        #連接數據庫
        #self.conn=pymysql.connect(host=host,port=port,user=user,password=passwd,db=database,charset='utf8')
        self.conn = pymysql.connect(host=mysql_host, user=mysql_user, password=mysql_passwd, db=mysql_db,port=mysql_port)
        #創建遊標對象
        self.cur=self.conn.cursor()

    def process_item(self, item, spider):
        #將item轉化爲dict類型
        data=dict(item)
        #將數據插入數據庫
        self.cur.execute("INSERT INTO movie_top250 (serial_number,film_name,film_country,film_time,film_type,film_maker,film_score,film_quote) VALUE (%(serial_number)s,%(film_name)s,%(film_country)s,%(film_time)s,%(film_type)s,%(film_maker)s,%(film_score)s,%(film_quote)s)",data)
        self.conn.commit()
        return item

我們來運行一下,看是否保存到數據庫,運行前記得,要在setting中開啓pipeline

最後,我們再來講一下基本的反爬機制,主要有設置頭文件中的User-Agent,設置代理ip,我就講講前面一種方法,因爲後一種方法需要代理服務器,我買不起,也就不講了。這裏又該在哪裏寫我們的代碼呢,我們再回去看看文章開頭的j框架圖,顯然,我們需要在Downloader middlwares中實現。來到middlwares.py文件中,聲明一個類,在類內的默認函數process_request中進行實現。當然,再次提醒,我們需要在setting文件中開啓此方法。

class random_user_agent(object):
    def process_request(self,request,spider):
        #user_agent設備列表
        USER_AGENT_LIST = ['MSIE (MSIE 6.0; X11; Linux; i686) Opera 7.23',
                           'Opera/9.20 (Macintosh; Intel Mac OS X; U; en)',
                           'Opera/9.0 (Macintosh; PPC Mac OS X; U; en)',
                           'iTunes/9.0.3 (Macintosh; U; Intel Mac OS X 10_6_2; en-ca)',
                           'Mozilla/4.76 [en_jp] (X11; U; SunOS 5.8 sun4u)',
                           'iTunes/4.2 (Macintosh; U; PPC Mac OS X 10.2)',
                           'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:5.0) Gecko/20100101 Firefox/5.0',
                           'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:9.0) Gecko/20100101 Firefox/9.0',
                           'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:16.0) Gecko/20120813 Firefox/16.0',
                           'Mozilla/4.77 [en] (X11; I; IRIX;64 6.5 IP30)',
                           'Mozilla/4.8 [en] (X11; U; SunOS; 5.7 sun4u)']
        #從USER_AGENT_LIST隨機選擇
        user_agent=random.choice(USER_AGENT_LIST)
        request.headers["User_Agent"]=user_agent

 

                                                     總結

這篇文章只能算是scrapy爬蟲的一個入門,在各式各樣的需求中,爬蟲項目要比這複雜的多,而且網站的反爬機制也複雜的多,需要學的還很多,此文章是爲了加深自己的記憶和理解,也是想給剛入門的人一個參考,文章有什麼錯誤的地方,希望各位大佬指出,也希望給我一些指點和幫助

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章