爬蟲學(xué)習(xí)之基于Scrapy的自動(dòng)登錄

概述


在前面兩篇(爬蟲學(xué)習(xí)之基于Scrapy的網(wǎng)絡(luò)爬蟲爬蟲學(xué)習(xí)之簡單的網(wǎng)絡(luò)爬蟲)文章中我們通過兩個(gè)實(shí)際的案例狮含,采用不同的方式進(jìn)行了內(nèi)容提取。我們對網(wǎng)絡(luò)爬蟲有了一個(gè)比較初級的認(rèn)識旷赖,只要發(fā)起請求獲取響應(yīng)的網(wǎng)頁內(nèi)容舟陆,然后對內(nèi)容進(jìn)行格式化存儲。很多時(shí)候我們抓取到的內(nèi)容可能會(huì)發(fā)生重復(fù)勉痴,也有可能是需要計(jì)算或者組織過的全新的內(nèi)容甚至是需要登錄后才能訪問的內(nèi)容秒际, 那么這一篇我們來學(xué)習(xí)一下Scrapy的Item部分以及了解如何使用Scrapy來進(jìn)行自動(dòng)登錄悬赏。

起步


首先我們使用Scrapy的命令行創(chuàng)建一個(gè)新的項(xiàng)目

scrapy startproject douban

運(yùn)行后,我們就有了下面這樣的目錄結(jié)構(gòu)

+ douban                               # 根目錄
    |- douban                          # Python的項(xiàng)目目錄
        |- spiders                     # 爬蟲Spider部分娄徊,用于提取網(wǎng)頁內(nèi)容
            |- __init__.py
        |- __init__.py
        |- items.py                    # 爬蟲item闽颇, 用于定義數(shù)據(jù)結(jié)構(gòu)
        |- pipelines.py                # 爬蟲pipeline,用于處理提取的結(jié)構(gòu)寄锐,比如清洗數(shù)據(jù)兵多、去重等
        |- settings.py                 # Scrapy框架參數(shù)項(xiàng)目參數(shù)設(shè)置
    |- scrapy.cfg                      # 爬蟲部署相關(guān)設(shè)置

Scrapy為我們生成了已經(jīng)組織好的目錄結(jié)構(gòu)尖啡,上面的注釋部分解釋了每個(gè)文件及目錄的作用。

建立目標(biāo)


本篇我們來建立兩個(gè)目標(biāo)剩膘,這兩個(gè)目標(biāo)都是基于豆瓣網(wǎng)

目標(biāo)一:抓取豆瓣TOP250的圖書信息并保存成csv文件
目標(biāo)二:抓取我的第一頁豆郵標(biāo)題(需要登錄)衅斩,并保存成csv文件

分析目標(biāo)一


目標(biāo)一是豆瓣的TOP250圖書信息,首先我們進(jìn)入到TOP250的列表(https://book.douban.com/top250) 怠褐,我用圖示圈出我們這次要爬取的內(nèi)容畏梆,具體請看圖示:

豆瓣圖書TOP250

從圖上的框線中我們主要圈出了書名、價(jià)格奈懒、出版年份奠涌、出版社、評分磷杏,其中出版年份溜畅,出版社以及價(jià)格是在一行中,這個(gè)我們需要進(jìn)一步處理极祸。
分頁的處理:總記錄是250條慈格,每頁是25條圖書信息,共分了10頁

實(shí)現(xiàn)目標(biāo)一


需要用到的概念:

Item
Item Pipeline

首先建立Scrapy的Item遥金, Scrapy的Item就是我們需要存儲的數(shù)據(jù)結(jié)構(gòu)浴捆,先修改items, 然后在spiders目錄中新建一個(gè)名為bookspider.py的Python文件,由于我們需要在一堆字符串中提取出出版社和價(jià)格等信息所以我們這里需要對抓取的內(nèi)容進(jìn)一步處理汰规, 在這之前還需要修改settings.py文件:

  1. 加入faker的模擬USER_AGENT數(shù)據(jù)防止被豆瓣屏蔽汤功,
  2. 也可以設(shè)置DEFAULT_REQUEST_HEADERS參數(shù)。
  3. 修改ITEM_PIPELINES

代碼如下所示:

items.py

# -*- coding: utf-8 -*-
'''by sudo rm -rf http://imchenkun.com'''
import scrapy


class DoubanBookItem(scrapy.Item):
    name = scrapy.Field()            # 書名
    price = scrapy.Field()           # 價(jià)格
    edition_year = scrapy.Field()    # 出版年份
    publisher = scrapy.Field()       # 出版社
    ratings = scrapy.Field()         # 評分

bookspider.py

# -*- coding:utf-8 -*-
'''by sudo rm -rf http://imchenkun.com'''
import scrapy
from douban.items import DoubanBookItem


class BookSpider(scrapy.Spider):
    name = 'douban-book'
    allowed_domains = ['douban.com']
    start_urls = [
        'https://book.douban.com/top250'
    ]

    def parse(self, response):
        # 請求第一頁
        yield scrapy.Request(response.url, callback=self.parse_next)

        # 請求其它頁
        for page in response.xpath('//div[@class="paginator"]/a'):
            link = page.xpath('@href').extract()[0]
            yield scrapy.Request(link, callback=self.parse_next)

    def parse_next(self, response):
        for item in response.xpath('//tr[@class="item"]'):
            book = DoubanBookItem()
            book['name'] = item.xpath('td[2]/div[1]/a/@title').extract()[0]
            book['price'] = item.xpath('td[2]/p/text()').extract()[0]
            book['ratings'] = item.xpath('td[2]/div[2]/span[2]/text()').extract()[0]
            yield book

pipelines.py

# -*- coding: utf-8 -*-
'''by sudo rm -rf http://imchenkun.com'''


class DoubanBookPipeline(object):
    def process_item(self, item, spider):
        info = item['price'].split(' / ')  # [法] 圣傲锵克蘇佩里 / 馬振聘 / 人民文學(xué)出版社 / 2003-8 / 22.00元
        item['name'] = item['name']
        item['price'] = info[-1]
        item['edition_year'] = info[-2]
        item['publisher'] = info[-3]
        return item

最后我們到douban的根目錄中執(zhí)行以下命令來運(yùn)行爬蟲來執(zhí)行并導(dǎo)出數(shù)據(jù)到csv文件

scrapy crawl douban-book -o douban_book_top250.csv

csv文件截圖如下:


導(dǎo)出的圖書數(shù)據(jù)

分析目標(biāo)二


目標(biāo)二是建立在理解了目標(biāo)一的基礎(chǔ)上進(jìn)行的,因?yàn)槎拱甑卿洿螖?shù)過多會(huì)有驗(yàn)證碼出現(xiàn)色解,這里提供一種手工填寫驗(yàn)證碼的方式茂嗓,暫時(shí)不討論如何去識別驗(yàn)證碼,目標(biāo)二的核心概念是如何提交POST表單和登錄成功后帶Cookie的請求科阎。首先我們可以看到頁面結(jié)構(gòu)如下圖所示:


豆瓣郵件列表

實(shí)現(xiàn)目標(biāo)二


定義Item

# -*- coding: utf-8 -*-import scrapy
'''by sudo rm -rf  http://imchenkun.com'''


class DoubanMailItem(scrapy.Item):
    sender_time = scrapy.Field()     # 發(fā)送時(shí)間
    sender_from = scrapy.Field()     # 發(fā)送人
    url = scrapy.Field()             # 豆郵詳細(xì)地址
    title = scrapy.Field()           # 豆郵標(biāo)題

定義doumailspider

# -*- coding:utf-8 -*-
'''by sudo rm -rf  http://imchenkun.com'''
import scrapy
from faker import Factory
from douban.items import DoubanMailItem
import urlparse

f = Factory.create()


class MailSpider(scrapy.Spider):
    name = 'douban-mail'
    allowed_domains = ['accounts.douban.com', 'douban.com']
    start_urls = [
        'https://www.douban.com/'
    ]
    headers = {
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
        'Accept-Encoding': 'gzip, deflate, br',
        'Accept-Language': 'zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3',
        'Connection': 'keep-alive',
        'Host': 'accounts.douban.com',
        'User-Agent': f.user_agent()
    }

    formdata = {
        'form_email': '您的賬號',
        'form_password': '您的密碼',
        # 'captcha-solution': '',
        # 'captcha-id': '',
        'login': '登錄',
        'redir': 'https://www.douban.com/',
        'source': 'None'
    }

    def start_requests(self):
        return [scrapy.Request(url='https://www.douban.com/accounts/login',
                               headers=self.headers,
                               meta={'cookiejar': 1},
                               callback=self.parse_login)]

    def parse_login(self, response):
        # 如果有驗(yàn)證碼要人為處理
        if 'captcha_image' in response.body:
            print 'Copy the link:'
            link = response.xpath('//img[@class="captcha_image"]/@src').extract()[0]
            print link
            captcha_solution = raw_input('captcha-solution:')
            captcha_id = urlparse.parse_qs(urlparse.urlparse(link).query, True)['id']
            self.formdata['captcha-solution'] = captcha_solution
            self.formdata['captcha-id'] = captcha_id
        return [scrapy.FormRequest.from_response(response,
                                                 formdata=self.formdata,
                                                 headers=self.headers,
                                                 meta={'cookiejar': response.meta['cookiejar']},
                                                 callback=self.after_login
                                                 )]

    def after_login(self, response):
        print response.status
        self.headers['Host'] = "www.douban.com"
        return scrapy.Request(url='https://www.douban.com/doumail/',
                              meta={'cookiejar': response.meta['cookiejar']},
                              headers=self.headers,
                              callback=self.parse_mail)

    def parse_mail(self, response):
        print response.status
        for item in response.xpath('//div[@class="doumail-list"]/ul/li'):
            mail = DoubanMailItem()
            mail['sender_time'] = item.xpath('div[2]/div/span[1]/text()').extract()[0]
            mail['sender_from'] = item.xpath('div[2]/div/span[2]/text()').extract()[0]
            mail['url'] = item.xpath('div[2]/p/a/@href').extract()[0]
            mail['title'] = item.xpath('div[2]/p/a/text()').extract()[0]
            print mail
            yield mail

這里需要注意的有三個(gè)地方:

  1. 第一個(gè)是meta中的cookiejar

Scrapy通過使用 cookiejar
Request meta key來支持單spider追蹤多cookie session述吸。默認(rèn)情況下其使用一個(gè)cookie jar(session),不過您可以傳遞一個(gè)標(biāo)示符來使用多個(gè)锣笨。

  1. start_requests 我們這里重寫了爬蟲爬取得第一個(gè)頁面蝌矛,這里一開始就進(jìn)去到登錄頁面
  2. 當(dāng)執(zhí)行爬蟲的時(shí)候,我們需要把打印出來的驗(yàn)證碼地址粘貼到瀏覽器中错英,手動(dòng)輸入到控制上完成驗(yàn)證入撒。

同目標(biāo)一一樣需要設(shè)置settings中的相關(guān)參數(shù),唯一不同的是ITEM_PIPELINES椭岩。

最后我們使用以下命令來啟動(dòng)爬蟲

scrapy crawl douban-mail -o douban_mail_page1.csv

csv文件截圖如下:


豆郵數(shù)據(jù)

Github地址:https://github.com/imchenkun/ick-spider/tree/master/douban

總結(jié)


本篇我們學(xué)習(xí)了如果定義Item以及如何對Item進(jìn)行進(jìn)一步處理(Item Pipeline)茅逮, 還通過登錄豆瓣的案例來了解了如果使用Scrapy進(jìn)行表單提交和Cookie追蹤璃赡,也了解了對于有驗(yàn)證碼的情況該如何處理,當(dāng)然我們這里暫時(shí)還不討論如何識別驗(yàn)證碼献雅。關(guān)于Scrapy的更高級的一些用法和特性可以進(jìn)一步閱讀Scrapy官網(wǎng)的文檔碉考。

特別申明:本文所提到的豆瓣網(wǎng)只是拿來進(jìn)行爬蟲的技術(shù)交流學(xué)習(xí),讀者涉及到的所有侵權(quán)問題都與本人無關(guān)挺身,也希望大家在學(xué)習(xí)實(shí)戰(zhàn)的過程中不要大量的爬取內(nèi)容對服務(wù)器造成負(fù)擔(dān)

本文首發(fā)在sudo rm -rf 采用署名(BY)-非商業(yè)性使用(NC)-禁止演繹(ND) 轉(zhuǎn)載請注明原作者

--EOF--

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末侯谁,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子章钾,更是在濱河造成了極大的恐慌墙贱,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件伍玖,死亡現(xiàn)場離奇詭異嫩痰,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)窍箍,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進(jìn)店門串纺,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人椰棘,你說我怎么就攤上這事纺棺。” “怎么了邪狞?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵祷蝌,是天一觀的道長。 經(jīng)常有香客問我帆卓,道長巨朦,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任剑令,我火速辦了婚禮糊啡,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘吁津。我一直安慰自己棚蓄,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布碍脏。 她就那樣靜靜地躺著梭依,像睡著了一般。 火紅的嫁衣襯著肌膚如雪典尾。 梳的紋絲不亂的頭發(fā)上役拴,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天,我揣著相機(jī)與錄音急黎,去河邊找鬼扎狱。 笑死侧到,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的淤击。 我是一名探鬼主播匠抗,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼污抬!你這毒婦竟也來了汞贸?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤印机,失蹤者是張志新(化名)和其女友劉穎矢腻,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體射赛,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡多柑,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了楣责。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片竣灌。...
    茶點(diǎn)故事閱讀 38,569評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖秆麸,靈堂內(nèi)的尸體忽然破棺而出初嘹,到底是詐尸還是另有隱情,我是刑警寧澤沮趣,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布屯烦,位于F島的核電站,受9級特大地震影響房铭,放射性物質(zhì)發(fā)生泄漏驻龟。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一缸匪、第九天 我趴在偏房一處隱蔽的房頂上張望迅脐。 院中可真熱鬧,春花似錦豪嗽、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至窃躲,卻和暖如春计贰,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背蒂窒。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工躁倒, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留荞怒,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓秧秉,卻偏偏與公主長得像褐桌,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子象迎,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評論 2 348

推薦閱讀更多精彩內(nèi)容