摘要:概述在前面兩篇爬蟲學習之基于的網絡爬蟲和爬蟲學習之簡單的網絡爬蟲文章中我們通過兩個實際的案例,采用不同的方式進行了內容提取。
概述
在前面兩篇(爬蟲學習之基于Scrapy的網絡爬蟲和爬蟲學習之簡單的網絡爬蟲)文章中我們通過兩個實際的案例,采用不同的方式進行了內容提取。我們對網絡爬蟲有了一個比較初級的認識,只要發起請求獲取響應的網頁內容,然后對內容進行格式化存儲。很多時候我們抓取到的內容可能會發生重復,也有可能是需要計算或者組織過的全新的內容甚至是需要登錄后才能訪問的內容, 那么這一篇我們來學習一下Scrapy的Item部分以及了解如何使用Scrapy來進行自動登錄。
起步首先我們使用Scrapy的命令行創建一個新的項目
scrapy startproject douban
運行后,我們就有了下面這樣的目錄結構
+ douban # 根目錄 |- douban # Python的項目目錄 |- spiders # 爬蟲Spider部分,用于提取網頁內容 |- __init__.py |- __init__.py |- items.py # 爬蟲item, 用于定義數據結構 |- pipelines.py # 爬蟲pipeline,用于處理提取的結構,比如清洗數據、去重等 |- settings.py # Scrapy框架參數項目參數設置 |- scrapy.cfg # 爬蟲部署相關設置
Scrapy為我們生成了已經組織好的目錄結構,上面的注釋部分解釋了每個文件及目錄的作用。
建立目標本篇我們來建立兩個目標,這兩個目標都是基于豆瓣網:
目標一:抓取豆瓣TOP250的圖書信息并保存成csv文件
目標二:抓取我的第一頁豆郵標題(需要登錄),并保存成csv文件
分析目標一目標一是豆瓣的TOP250圖書信息,首先我們進入到TOP250的列表(https://book.douban.com/top250) ,我用圖示圈出我們這次要爬取的內容,具體請看圖示:
從圖上的框線中我們主要圈出了書名、價格、出版年份、出版社、評分,其中出版年份,出版社以及價格是在一行中,這個我們需要進一步處理。
分頁的處理:總記錄是250條,每頁是25條圖書信息,共分了10頁。
實現目標一需要用到的概念:
Item
Item Pipeline
首先建立Scrapy的Item, Scrapy的Item就是我們需要存儲的數據結構,先修改items, 然后在spiders目錄中新建一個名為bookspider.py的Python文件,由于我們需要在一堆字符串中提取出出版社和價格等信息所以我們這里需要對抓取的內容進一步處理, 在這之前還需要修改settings.py文件:
加入faker的模擬USER_AGENT數據防止被豆瓣屏蔽,
也可以設置DEFAULT_REQUEST_HEADERS參數。
修改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() # 價格 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("http://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("http://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(" / ") # [法] 圣埃克蘇佩里 / 馬振聘 / 人民文學出版社 / 2003-8 / 22.00元 item["name"] = item["name"] item["price"] = info[-1] item["edition_year"] = info[-2] item["publisher"] = info[-3] return item
最后我們到douban的根目錄中執行以下命令來運行爬蟲來執行并導出數據到csv文件
scrapy crawl douban-book -o douban_book_top250.csv
csv文件截圖如下:
分析目標二目標二是建立在理解了目標一的基礎上進行的,因為豆瓣登錄次數過多會有驗證碼出現,這里提供一種手工填寫驗證碼的方式,暫時不討論如何去識別驗證碼,目標二的核心概念是如何提交POST表單和登錄成功后帶Cookie的請求。首先我們可以看到頁面結構如下圖所示:
實現目標二定義Item
# -*- coding: utf-8 -*-import scrapy """by sudo rm -rf http://imchenkun.com""" class DoubanMailItem(scrapy.Item): sender_time = scrapy.Field() # 發送時間 sender_from = scrapy.Field() # 發送人 url = scrapy.Field() # 豆郵詳細地址 title = scrapy.Field() # 豆郵標題
定義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): # 如果有驗證碼要人為處理 if "captcha_image" in response.body: print "Copy the link:" link = response.xpath("http://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("http://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
這里需要注意的有三個地方:
第一個是meta中的cookiejar
Scrapy 通過使用 cookiejar Request meta key來支持單spider追蹤多cookie session。默認情況下其使用一個cookie jar(session),不過您可以傳遞一個標示符來使用多個。
start_requests 我們這里重寫了爬蟲爬取得第一個頁面,這里一開始就進去到登錄頁面
當執行爬蟲的時候,我們需要把打印出來的驗證碼地址粘貼到瀏覽器中,手動輸入到控制上完成驗證。
同目標一一樣需要設置settings中的相關參數,唯一不同的是ITEM_PIPELINES。
最后我們使用以下命令來啟動爬蟲
scrapy crawl douban-mail -o douban_mail_page1.csv
csv文件截圖如下:
Github地址:https://github.com/imchenkun/ick-spider/tree/master/douban
總結本篇我們學習了如果定義Item以及如何對Item進行進一步處理(Item Pipeline), 還通過登錄豆瓣的案例來了解了如果使用Scrapy進行表單提交和Cookie追蹤,也了解了對于有驗證碼的情況該如何處理,當然我們這里暫時還不討論如何識別驗證碼。關于Scrapy的更高級的一些用法和特性可以進一步閱讀Scrapy官網的文檔。
特別申明:本文所提到的豆瓣網只是拿來進行爬蟲的技術交流學習,讀者涉及到的所有侵權問題都與本人無關,也希望大家在學習實戰的過程中不要大量的爬取內容對服務器造成負擔
本文首發在sudo rm -rf 采用署名(BY)-非商業性使用(NC)-禁止演繹(ND) 轉載請注明原作者
--EOF--
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/38070.html
摘要:不過不用擔心,中有很多非常優秀的爬蟲框架,比如我們接下來要學習到的。結合以上分析我們基本確定了本次爬蟲的各個路線入口,接下來我們就開始通過程序來實現本次的目標。這里我們的目的是建立一種寫爬蟲的思路,而不在于怎么使用工具來爬數據。 概述 在上一篇文章《爬蟲學習之一個簡單的網絡爬蟲》中我們對爬蟲的概念有了一個初步的認識,并且通過Python的一些第三方庫很方便的提取了我們想要的內容,但是...
摘要:時間永遠都過得那么快,一晃從年注冊,到現在已經過去了年那些被我藏在收藏夾吃灰的文章,已經太多了,是時候把他們整理一下了。那是因為收藏夾太亂,橡皮擦給設置私密了,不收拾不好看呀。 ...
摘要:楚江數據是專業的互聯網數據技術服務,現整理出零基礎如何學爬蟲技術以供學習,。本文來源知乎作者路人甲鏈接楚江數據提供網站數據采集和爬蟲軟件定制開發服務,服務范圍涵蓋社交網絡電子商務分類信息學術研究等。 楚江數據是專業的互聯網數據技術服務,現整理出零基礎如何學爬蟲技術以供學習,http://www.chujiangdata.com。 第一:Python爬蟲學習系列教程(來源于某博主:htt...
摘要:最近這兩周在忙著給公司爬一點數據,更文的速度有一點下降,預計今天就爬完了,總結總結經驗。一個爬蟲的框架?;镜葍r于選擇其中的文字提取屬性文檔,這個我不會,我也沒看使用這個類庫解析如請求方式可以用來給中文字符數據放入傳遞即可。 最近這兩周在忙著給公司爬一點數據,更文的速度有一點下降,預計今天就爬完了,總結總結經驗。 其實之前我司是有專門做爬蟲的,不用前端這邊出人干活。后來那人離職了,有可...
摘要:最近這兩周在忙著給公司爬一點數據,更文的速度有一點下降,預計今天就爬完了,總結總結經驗。一個爬蟲的框架?;镜葍r于選擇其中的文字提取屬性文檔,這個我不會,我也沒看使用這個類庫解析如請求方式可以用來給中文字符數據放入傳遞即可。 最近這兩周在忙著給公司爬一點數據,更文的速度有一點下降,預計今天就爬完了,總結總結經驗。 其實之前我司是有專門做爬蟲的,不用前端這邊出人干活。后來那人離職了,有可...
閱讀 1839·2021-09-22 15:23
閱讀 3267·2021-09-04 16:45
閱讀 1873·2021-07-29 14:49
閱讀 2773·2019-08-30 15:44
閱讀 1524·2019-08-29 16:36
閱讀 1042·2019-08-29 11:03
閱讀 1510·2019-08-26 13:53
閱讀 509·2019-08-26 11:57