1. 程式人生 > >scrapy爬蟲之item/itemloader機制爬取豆瓣電影top250

scrapy爬蟲之item/itemloader機制爬取豆瓣電影top250

簡介

前面的博文網頁的基本解析流程就是先通過 css/xpath 方法進行解析,然後再把值封裝到 Item 中,如果有特殊需要的話還要對解析到的資料進行轉換處理,這樣當解析程式碼或者資料轉換要求過多的時候,會導致程式碼量變得極為龐大,從而降低了可維護性。同時在 sipider 中編寫過多的資料處理程式碼某種程度上也違背了單一職責的程式碼設計原則。我們需要使用一種更加簡潔的方式來獲取與處理網頁資料,ItemLoader 就是用來完成這件事情的。
因此,我們從一開始就應該適應item/itemloader來解析資料。

網頁分析

豆瓣電影top250

黃色標註的就是我們需要抓取的內容。

實現

一、定義item類
為了將網頁解析後獲取的資料進行格式化,便於資料的傳遞與進一步的操作,Scrapy 提供了 Item 類來對資料進行封裝。
要使用 Item 類非常簡單,直接繼承 scrapy 的 Item 類即可,然後可以定義相應的屬性欄位來對資料進行儲存,其欄位型別為 scrapy.Field()。 Scrapy 只提供了 Field() 一種欄位型別,可以用來儲存任意型別的資料

vim item.py
from scrapy.loader.processors import Join, MapCompose, TakeFirst
class Movietop250(scrapy.Item):
    rank = scrapy.Field()
    title = scrapy.Field(output_processor=Join())
    link = scrapy.Field()
    star = scrapy.Field(output_processor=Join(','))
    quote = scrapy.Field()

從上圖看出:
title有title和other標籤,此處我們需要使用itemloader的output_processor將其join到一起;star也是如此。

二、itemloader解析資料
ItemLoader 類位於 scrapy.loader ,它可以接收一個 Item 例項來指定要載入的 Item, 然後指定 response 或者 selector 來確定要解析的內容,最後提供了 add_css()、 add_xpath() 方法來對通過 css 、 xpath 解析賦值,還有 add_value() 方法來單獨進行賦值

from scrapy.loader import ItemLoader
from douban.items import Movietop250
    def parse_movietop250(self, response)
:
''' 抓取豆瓣電影top250 ''' print(response.url) #scrapy shell分析xpath語法 #from scrapy.shell import inspect_response #inspect_response(response, self) for eachitem in response.xpath('//div[@class="item"]'): movie = ItemLoader(item=Movietop250(), selector=eachitem) movie.add_xpath('rank', 'div[@class="pic"]/em/text()') #movie.add_xpath('title', 'div[@class="pic"]/a/img/@alt') movie.add_xpath('title', 'div[@class="info"]/div[@class="hd"]/a/span/text()') movie.add_xpath('link', 'div[@class="pic"]/a/@href') #movie.add_xpath('star', 'div[@class="info"]/div[@class="bd"]/div[@class="star"]/span[@class="rating_num"]/text()') movie.add_xpath('star', 'div[@class="info"]/div[@class="bd"]/div[@class="star"]/span/text()') movie.add_xpath('quote', 'div[@class="info"]/div[@class="bd"]/p[@class="quote"]/span[@class="inq"]/text()') yield movie.load_item() next_page = response.xpath('//div[@class="paginator"]/span[@class="next"]/a/@href').extract_first() if next_page: yield response.follow(next_page, meta={"cookiejar":response.meta["cookiejar"]}, callback=self.parse_movietop250)

注意:
ItemLoader 預設都會返回一個 list。在之前的方式中我們都是通過 extract_first() 獲取第一個值或者通過 extract() 解析到值後進行遍歷的。在 ItemLoader 中,為我們提供了 input_processor 和output_processor 來對資料的輸入與輸出進行解析。其中output_processor提供了Join, MapCompose, TakeFirst等方法。
如:add_xpath接收的引數是list型別的div[@class=”info”]/div[@class=”hd”]/a/span/text(),然後
由output_processor將list中的資料join到一起,再賦值給field。

三、完整程式碼及爬取資料
完整程式碼還是在登陸豆瓣的基礎上進行抓取,登陸
豆瓣程式碼請參看scrapy爬蟲之模擬登入豆瓣

# -*- coding: utf-8 -*-
#登陸豆瓣,學習使用itme/item_loader,抓取豆瓣電影top250
import scrapy
import urllib
from PIL import Image
from scrapy.loader import ItemLoader
from douban.items import Movietop250


class Movietop250Spider(scrapy.Spider):
    name = 'movieTop250'
    allowed_domains = ['douban.com']
#    start_urls = ['http://www.douban.com/']
    headers = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.221 Safari/537.36 SE 2.X MetaSr 1.0"}

    def start_requests(self):
    '''
    重寫start_requests,請求登入頁面
    '''
    return [scrapy.FormRequest("https://accounts.douban.com/login", headers=self.headers, meta={"cookiejar":1}, callback=self.parse_before_login)]

    def parse_before_login(self, response):
    '''
    登入表單填充,檢視驗證碼
    '''
    print("登入前表單填充")
    captcha_id = response.xpath('//input[@name="captcha-id"]/@value').extract_first()
    captcha_image_url = response.xpath('//img[@id="captcha_image"]/@src').extract_first()
    if captcha_image_url is None:
        print("登入時無驗證碼")
        formdata = {
                "source": "index_nav",
                "form_email": "[email protected]",
                #請填寫你的密碼
                "form_password": "*******",
            }
    else:   
        print("登入時有驗證碼")
        save_image_path = "/home/yanggd/python/scrapy/douban/douban/spiders/captcha.jpeg"
        #將圖片驗證碼下載到本地
        urllib.urlretrieve(captcha_image_url, save_image_path)
        #開啟圖片,以便我們識別圖中驗證碼
        try:
            im = Image.open('captcha.jpeg')
            im.show()
        except:
            pass

        #手動輸入驗證碼
        captcha_solution = raw_input('根據開啟的圖片輸入驗證碼:')       
        formdata = {
                "source": "None",
                "redir": "https://www.douban.com",
                "form_email": "[email protected]",
                #請填寫你的密碼
                                "form_password": "*******",
                "captcha-solution": captcha_solution,
                "captcha-id": captcha_id,
                "login": "登入",
            }


    print("登入中")    
    #提交表單
    return scrapy.FormRequest.from_response(response, meta={"cookiejar":response.meta["cookiejar"]}, headers=self.headers, formdata=formdata, callback=self.parse_after_login)

    def parse_after_login(self, response):
    '''
    驗證登入是否成功
    '''
    account = response.xpath('//a[@class="bn-more"]/span/text()').extract_first()
    if account is None:
        print("登入失敗") 
    else:
        print(u"登入成功,當前賬戶為 %s" %account)
        print("進入豆瓣電影top250頁面")
        yield scrapy.Request('https://movie.douban.com/top250', meta={"cookiejar":response.meta["cookiejar"]}, headers=self.headers, callback=self.parse_movietop250)

    def parse_movietop250(self, response):
    '''
    抓取豆瓣電影top250
    '''
    print(response.url)
    #scrapy shell分析xpath語法
    #from scrapy.shell import inspect_response
    #inspect_response(response, self)
    for eachitem in response.xpath('//div[@class="item"]'):
        movie = ItemLoader(item=Movietop250(), selector=eachitem)
        movie.add_xpath('rank', 'div[@class="pic"]/em/text()')
        #movie.add_xpath('title', 'div[@class="pic"]/a/img/@alt')
        movie.add_xpath('title', 'div[@class="info"]/div[@class="hd"]/a/span/text()')
        movie.add_xpath('link', 'div[@class="pic"]/a/@href')
        #movie.add_xpath('star', 'div[@class="info"]/div[@class="bd"]/div[@class="star"]/span[@class="rating_num"]/text()')
        movie.add_xpath('star', 'div[@class="info"]/div[@class="bd"]/div[@class="star"]/span/text()')
        movie.add_xpath('quote', 'div[@class="info"]/div[@class="bd"]/p[@class="quote"]/span[@class="inq"]/text()')
        yield movie.load_item()

    next_page = response.xpath('//div[@class="paginator"]/span[@class="next"]/a/@href').extract_first()
    if next_page:
        yield response.follow(next_page, meta={"cookiejar":response.meta["cookiejar"]}, callback=self.parse_movietop250)

執行爬蟲並將輸出儲存為json

scrapy crawl movieTop250 -o movietop250.json
vim movietop250.json
[
{"quote": ["希望讓人自由。"], "link": ["https://movie.douban.com/subject/1292052/"], "star": "9.6,941921人評價", "rank": ["1"], "title": "肖申克的救贖  / The Shawshank Redemption  / 月黑高飛(港)  /  刺激1995(臺)"},
{"quote": ["風華絕代。"], "link": ["https://movie.douban.com/subject/1291546/"], "star": "9.5,682519人評價", "rank": ["2"], "title": "霸王別姬  / 再見,我的妾  /  Farewell My Concubine"},
{"quote": ["怪蜀黍和小蘿莉不得不說的故事。"], "link": ["https://movie.douban.com/subject/1295644/"], "star": "9.4,892822人評價", "rank": ["3"], "title": "這個殺手不太冷  / Léon  / 殺手萊昂  /  終極追殺令(臺)"},
{"quote": ["一部美國近現代史。"], "link": ["https://movie.douban.com/subject/1292720/"], "star": "9.4,759287人評價", "rank": ["4"], "title": "阿甘正傳  / Forrest Gump  / 福雷斯特·岡普"},
{"quote": ["最美的謊言。"], "link": ["https://movie.douban.com/subject/1292063/"], "star": "9.5,443739人評價", "rank": ["5"], "title": "美麗人生  / La vita è bella  / 一個快樂的傳說(港)  /  Life Is Beautiful"},
{"quote": ["最好的宮崎駿,最好的久石讓。 "], "link": ["https://movie.douban.com/subject/1291561/"], "star": "9.2,709397人評價", "rank": ["6"], "title": "千與千尋  / 千と千尋の神隠し  / 神隱少女(臺)  /  Spirited Away"},
{"quote": ["拯救一個人,就是拯救整個世界。"], "link": ["https://movie.douban.com/subject/1295124/"], "star": "9.4,406435人評價", "rank": ["7"], "title": "辛德勒的名單  / Schindler's List  / 舒特拉的名單(港)  /  辛德勒名單"},
{"quote": ["失去的才是永恆的。 "], "link": ["https://movie.douban.com/subject/1292722/"], "star": "9.2,700354人評價", "rank": ["8"], "title": "泰坦尼克號  / Titanic  / 鐵達尼號(港 / 臺)",
...........
}
]

相關推薦

scrapy爬蟲item/itemloader機制豆瓣電影top250

簡介 前面的博文網頁的基本解析流程就是先通過 css/xpath 方法進行解析,然後再把值封裝到 Item 中,如果有特殊需要的話還要對解析到的資料進行轉換處理,這樣當解析程式碼或者資料轉換要求過多的時候,會導致程式碼量變得極為龐大,從而降低了可維護性。同時在

Scrapy爬蟲(4)豆瓣電影Top250圖片

  在用Python的urllib和BeautifulSoup寫過了很多爬蟲之後,本人決定嘗試著名的Python爬蟲框架——Scrapy.   本次分享將詳細講述如何利用Scrapy來下載豆瓣電影Top250, 主要解決的問題有: 如何利用ImagesPi

【Python爬蟲Scrapy框架運用1—豆瓣電影top250電影資訊(1)

一、Step step1: 建立工程專案 1.1建立Scrapy工程專案 E:\>scrapy startproject 工程專案 1.2使用Dos指令檢視工程資料夾結構 E:\>tree /f step2: 建立spid

爬蟲學習11:豆瓣電影TOP250並存入資料庫

     本次實驗主要測試使用PyMySQL庫寫資料進MySQL,爬取資料使用XPATH和正則表示式,在很多場合可以用XPATH提取資料,但有些資料項在網頁中沒有明顯特徵,用正則表示式反而反而更輕鬆獲取資料。直接上程式碼:from lxml import etree impo

【Python3爬蟲Scrapy豆瓣電影TOP250

今天要實現的就是使用是scrapy爬取豆瓣電影TOP250榜單上的電影資訊。 步驟如下: 一、爬取單頁資訊 首先是建立一個scrapy專案,在資料夾中按住shift然後點選滑鼠右鍵,選擇在此處開啟命令列視窗,輸入以下程式碼: scrapy startprojec

scrapy豆瓣電影top250

imp port 爬取 all lba item text request top 1 # -*- coding: utf-8 -*- 2 # scrapy爬取豆瓣電影top250 3 4 import scrapy 5 from douban.items i

Scrapy豆瓣電影top250電影數據、海報,MySQL存儲

p地址 rom gin ani char 代碼 pipeline print 關閉數據庫 從GitHub得到完整項目(https://github.com/daleyzou/douban.git)1、成果展示數據庫本地海報圖片2、環境(1)已安裝Scrapy的Pycharm

使用scrapy豆瓣電影Top250

根據官方文件做的簡單練習,唯一遇到的問題就是爬取返回403.解決方法是在settings.py檔案中增加以下引數: USER_AGENT = 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Ch

scrapy ------ 豆瓣電影TOP250

轉載自 —> 原文 #items.py # -*- coding: utf-8 -*- import scrapy class DoubanMovieItem(scrapy.Item): ranking = scrapy.Field() #排名 mo

案例學python——案例三:豆瓣電影資訊入庫 一起學爬蟲——通過豆瓣電影top250學習requests庫的使用

  閒扯皮 昨晚給高中的妹妹微信講題,函式題,小姑娘都十二點了還迷迷糊糊。今天凌晨三點多,被連續的警報聲給驚醒了,以為上海拉了防空警報,難不成地震,空襲?難道是樓下那個車主車子被堵了,長按喇叭?開窗看看,好像都不是。好鬼畜的警報聲,家裡也沒裝報警器啊,莫不成家裡煤氣漏了?起床循聲而查,報警

Python3 Scrapy框架學習二:豆瓣電影Top250

開啟專案裡的items.py檔案,定義如下變數, import scrapy from scrapy import Item,Field class DoubanItem(scrapy.Item): # define the fields for your it

03_使用scrapy框架豆瓣電影TOP250

前言:   本次專案是使用scrapy框架,爬取豆瓣電影TOP250的相關資訊。其中涉及到代理IP,隨機UA代理,最後將得到的資料儲存到mongoDB中。本次爬取的內容實則不難。主要是熟悉scrapy相關命令以及理解框架各部分的作用。 1、本次目標   爬取豆瓣電影TOP250的資訊,將得到的資料儲

一起學爬蟲——通過豆瓣電影top250學習requests庫的使用

學習一門技術最快的方式是做專案,在做專案的過程中對相關的技術查漏補缺。 本文通過爬取豆瓣top250電影學習python requests的使用。 1、準備工作 在pycharm中安裝request庫 請看上圖,在pycharm中依次點選:File->Settings。然後會彈出下圖的介面: 點選2

scrapy ------ 豆瓣電影TOP250

轉載自 —> 原文 #items.py # -*- coding: utf-8 -*- import scrapy class DoubanMovieItem(scrapy.Item): ranking = scrapy.Field()

【go語言爬蟲】go語言豆瓣電影top250

抓取欄位:電影名稱、評分、評價人數 二、執行: 正在抓取第0頁…… 肖申克的救贖 9.6 824764人 這個殺手不太冷 9.4 791399人 霸王別姬 9.5 589028人 阿甘正傳 9.4 678850人 美麗人生 9.5 3940

(7)Python爬蟲——豆瓣電影Top250

利用python爬取豆瓣電影Top250的相關資訊,包括電影詳情連結,圖片連結,影片中文名,影片外國名,評分,評價數,概況,導演,主演,年份,地區,類別這12項內容,然後將爬取的資訊寫入Excel表中。基本上爬取結果還是挺好的。具體程式碼如下: #!/us

scrapy入門實戰練習(一)----豆瓣電影top250

轉自知乎網工具和環境語言:python 2.7IDE: Pycharm瀏覽器:Chrome爬蟲框架:Scrapy 1.2.1教程正文觀察頁面結構通過觀察頁面決定讓我們的爬蟲獲取每一部電影的排名、電影名稱、評分和評分的人數。宣告ItemItems爬取的主要目標就是從非結構性的資

[Python/爬蟲]利用xpath豆瓣電影top250

今天學習了一下xpath 感覺功能非常的強大,但是如果不太懂前端的小夥伴們可能比較吃力,建議看一下html的一些語法結構,程式碼如下: #!/usr/bin/env python import r

python爬蟲——豆瓣電影top250資訊並載入到MongoDB資料庫中

最近在學習關於爬蟲方面的知識,因為剛開始接觸,還是萌新,所以有什麼錯誤的地方,歡迎大家指出 from multiprocessing import Pool from urllib.request import Request, urlopen import re, pymongo index

python爬蟲(一)豆瓣電影Top250

提示:完整程式碼附在文末 一、需要的庫           requests:獲得網頁請求           BeautifulSoup:處理資料,獲得所需要的資料 二、爬取豆瓣電影Top250           爬取內容為:豆瓣評分前二百五位電影的名字、主演、