[scrapy]scrapy按分類爬取豆瓣電影基礎信息

Scrapy簡介

Scrapy是一個為了爬取網站數據,提取結構性數據而編寫的應用框架。

Scrapy入門請看官方文檔: [ scrapy官方文檔 ](http://scrapy-
chs.readthedocs.io/zh_CN/1.0/intro/tutorial.html)

本爬蟲簡介

本爬蟲實現按分類爬取豆瓣電影信息,一次爬取一個分類,且自動切換代理池,防止ip在訪問過多過頻繁后無效。

分類如圖所示:

實現-scrapy中間件

scrapy基礎框架參考上面的官方教程,搭建好基礎框架后,本爬蟲特殊之處在于為了防止爬蟲被封,采用了輪換代理和agent的中間件。

agent輪換池:

簡單的寫一個user_agent_list來使得每次的agent不同,原理簡單,代碼如下:

class RotateUserAgentMiddleware(UserAgentMiddleware):  #輪換代理agent
    def __init__(self, user_agent=''):
        self.user_agent = user_agent

    def process_request(self, request, spider):
        ua = random.choice(self.user_agent_list)
        if ua:
            #print '-----------------------Using user-agent:', ua, '------------------------'
            request.headers.setdefault('User-Agent', ua)

            # the default user_agent_list composes chrome,IE,firefox,Mozilla,opera,netscape

    # for more user agent strings,you can find it in http://www.useragentstring.com/pages/useragentstring.php
    user_agent_list = [ \
        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1" \
        "Mozilla/5.0 (X11; CrOS i686 2268.111.0) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11", \
        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1092.0 Safari/536.6", \
        "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1090.0 Safari/536.6", \
        "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/19.77.34.5 Safari/537.1", \
        "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.9 Safari/536.5", \
        "Mozilla/5.0 (Windows NT 6.0) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.36 Safari/536.5", \
        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3", \
        "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3", \
        "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_0) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3", \
        "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3", \
        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3", \
        "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3", \
        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3", \
        "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3", \
        "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.0 Safari/536.3", \
        "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24", \
        "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24"
    ]

ip輪換池:

采用了一位大神cocoakekeyu寫的中間件 Github地址
,并不認識他,但是為他點贊。代碼在這里不貼了,可以去Github看。

** “一個用于scrapy爬蟲的自動代理中間件。可自動抓取和切換代理,自定義抓取和切換規則。” **

**
**

**
**

實現-爬蟲實現

item.py

class DoubanItem(scrapy.Item):
    movie_name = scrapy.Field()
    movie_director = scrapy.Field()
    movie_writer = scrapy.Field()
    movie_starring = scrapy.Field()
    movie_category = scrapy.Field()
    movie_country = scrapy.Field()
    #movie_language = scrapy.Field()
    movie_date = scrapy.Field()
    movie_time = scrapy.Field()
    movie_star = scrapy.Field()
    movie_5score = scrapy.Field()
    movie_4score = scrapy.Field()
    movie_3score = scrapy.Field()
    movie_2score = scrapy.Field()
    movie_1score = scrapy.Field()
    movie_describe = scrapy.Field()
    pass

看這item名都不用我解釋...

doubanlist_spider.py

先貼上代碼:

class doubanlistSpider(scrapy.Spider):
    name = "doubanlist"
    allowed_domains = ["movie.douban.com"]
    start_urls = [
        "https://movie.douban.com/tag/%E5%8A%A8%E7%94%BB"
    ]


    def parse(self, response):
        for href in response.xpath('//a[@class="nbg"]/@href'):
            url = href.extract()
            yield scrapy.Request(url, callback=self.parse_each_movie)
        next_page = response.xpath('//span[@class="next"]/a/@href').extract()
        if next_page:
            print '--------------Finding next page: [%s] --------------------------', next_page
            yield scrapy.Request(next_page[0], callback=self.parse)
        else:
            print '--------------There is no more page!--------------------------'


    def parse_each_movie(self, response):
        item = DoubanItem()
        item['movie_name'] = response.xpath('//span[@property="v:itemreviewed"]/text()').extract()
        item['movie_director'] = response.xpath('//a[@rel="v:directedBy"]/text()').extract()
        item['movie_writer'] = response.xpath('//span[@class="attrs"][2]/a/text()').extract()
        item['movie_starring'] = response.xpath('//a[@rel="v:starring"]/text()').extract()
        item['movie_category'] = response.xpath('//span[@property="v:genre"]/text()').extract()
        #item['movie_language'] = response.xpath('//*[@id="info"]').re(r'</span> (.*)<br>\n')[2]
        item['movie_date'] = response.xpath('//span[@property="v:initialReleaseDate"]/text()').extract()
        item['movie_time'] = response.xpath('//span[@property="v:runtime"]/text()').extract()
        item['movie_star'] = response.xpath('//strong[@property="v:average"]/text()').extract()
        item['movie_5score'] = response.xpath('//span[@class="rating_per"][1]/text()').extract()
        item['movie_4score'] = response.xpath('//span[@class="rating_per"][2]/text()').extract()
        item['movie_3score'] = response.xpath('//span[@class="rating_per"][3]/text()').extract()
        item['movie_2score'] = response.xpath('//span[@class="rating_per"][4]/text()').extract()
        item['movie_1score'] = response.xpath('//span[@class="rating_per"][5]/text()').extract()
        item['movie_describe'] = response.xpath('//*[@id="link-report"]/span/text()').re(r'\S+')

        check_item = response.xpath('//*[@id="info"]').re(r'</span> (.*)<br>\n')[1]
        result = self.check_contain_chinese(check_item)
        if result:
            item['movie_country'] = response.xpath('//*[@id="info"]').re(r'</span> (.*)<br>\n')[1]
        else:
            item['movie_country'] = response.xpath('//*[@id="info"]').re(r'</span> (.*)<br>\n')[2]

        yield item

    def check_contain_chinese(self, check_str):
        for ch in check_str.decode('utf-8'):
            if u'\u4e00' <= ch <= u'\u9fff':
                return True
        return False

def parse(self, response):從https://movie.douban.com/tag/%E5%8A%A8%E7%94%BB(某一特
定分類)開始,爬取20條本頁的電影,之后判定“下一頁”按鈕是否存在,如果存在則繼續爬取下一頁。

def parse_each_movie(self, response):對于每個電影詳細頁,爬取所需要的信息,全部使用xpath

中間一段是在爬取電影國家信息時,由于有不同情況的網頁(可能是新老頁面交替),需要不同處理,不然會爬到不正確的信息,xpath定位不準。

def check_contain_chinese:為了確定爬取的中文內容為中文字符串,需要進行判斷。

總結

具體項目請查看:https://github.com/qqxx6661/scrapy_yzd

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,732評論 6 539
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,214評論 3 426
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,781評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,588評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,315評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,699評論 1 327
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,698評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,882評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,441評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,189評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,388評論 1 372
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,933評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,613評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,023評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,310評論 1 293
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,112評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,334評論 2 377

推薦閱讀更多精彩內容