Scrapy定向爬虫教程(二)——提取网页内容
本節內容
在這一小結,我將介紹如何使用Scrapy通過Selector選擇器從網頁中提取出我們想要的內容,并將這些內容存放到本地文件。
我們的目標網頁是http://www.heartsong.top/forum.php?mod=viewthread&tid=8,一個有七層樓的帖子。我們要獲取到每一層樓的下列信息:
- 所屬主題帖的標題
- 所屬主題帖的url
- 這一樓層的作者
- 這一樓層的發表時間
- 這一樓層的內容
Selector選擇器
在Scrapy中,也可以使用BeautifulSoup來解析網頁,但是,我們推薦使用Scrapy自帶的Selector選擇器來解析網頁,沒別的原因,效率高。Selector選擇器有XPath方法和css方法兩種選擇方法,我使用的是XPath方法。
XPath
XPath 是一門在 XML 文檔中查找信息的語言。因為網上的教程有很多,在此處推薦兩個,我自己就不多講了。一個菜鳥教程的XPath文字教程,一個是極客學院的XPath視頻教程,后者需要實名認證一下就可以觀看,也不麻煩,個人比較推崇后者,老師講的很易懂。相信我,根據教程只需要半個小時你就能明白XPath,再根據下面我的代碼對照鞏固一下,你就能掌握它了。
使用Chrome分析網頁
我們使用Chrome瀏覽器(firefox也是類似的)來分析網頁,分析我們的XPath該怎么去寫,比如說我們現在要分析帖子的標題
右鍵帖子標題,選擇檢查
此時,Chrome的調試工具會跳出來,并且自動定位到源代碼中我們要檢查的元素的位置
之后根據代碼結構我們很輕松的就得出其XPath
其實在某些時候也可以直接右鍵元素,選擇copy xpath,但是這種方法在實踐中用處基本為零,因為很難去找出多個網頁的共同特質,所以一般情況下我們還是要自己去分析。
在這里有必要提醒一個神坑,在下面代碼中也有體現,詳見我從前寫的這篇文章Scrapy匹配xpath時tbody標簽的問題
這個坑給我的啟示是,當發現了感覺不能用科學解釋的錯誤的時候,就檢查一下獲取到的源代碼吧!
代碼
不說廢話了,直接上代碼。
首先,修改items.py文件,定義好我們要提取的內容
然后來到heartsong_spider.py,編寫爬蟲
# -*- coding: utf-8 -*-# import scrapy # 可以寫這句注釋下面兩句,不過下面要更好 from scrapy.spiders import Spider from scrapy.selector import Selector from heartsong.items import HeartsongItem # 此處如果報錯是pyCharm的原因class HeartsongSpider(Spider):name = "heartsong"allowed_domains = ["heartsong.top"] # 允許爬取的域名,非此域名的網頁不會爬取start_urls = ["http://www.heartsong.top/forum.php?mod=viewthread&tid=8" # 起始url,此例只爬這個頁面]def parse(self, response):selector = Selector(response) # 創建選擇器table = selector.xpath('//*[starts-with(@id, "pid")]') # 取出所有的樓層for each in table: # 對于每一個樓層執行下列操作item = HeartsongItem() # 實例化一個Item對象item['title'] = selector.xpath('//*[@id="thread_subject"]/text()').extract()[0]item['author'] = \each.xpath('tr[1]/td[@class="pls"]/div[@class="pls favatar"]/div[@class="pi"]/div[@class="authi"]/a/text()').extract()[0]item['post_time'] = \each.xpath('tr[1]/td[@class="plc"]/div[@class="pi"]').re(r'[0-9]+-[0-9]+-[0-9]+ [0-9]+:[0-9]+:[0-9]+')[0].decode("unicode_escape")content_list = each.xpath('.//td[@class="t_f"]').xpath('string(.)').extract()content = "".join(content_list) # 將list轉化為stringitem['url'] = response.url # 用這種方式獲取網頁的url# 把內容中的換行符,空格等去掉item['content'] = content.replace('\r\n', '').replace(' ', '').replace('\n', '')yield item # 將創建并賦值好的Item對象傳遞到PipeLine當中進行處理最后到pipelines.py中保存爬取到的數據:
# -*- coding: utf-8 -*-import heartsong.settingsclass HeartsongPipeline(object):def process_item(self, item, spider):file = open("items.txt", "a") # 以追加的方式打開文件,不存在則創建# 因為item中的數據是unicode編碼的,為了在控制臺中查看數據的有效性和保存,# 將其編碼改為utf-8item_string = str(item).decode("unicode_escape").encode('utf-8')file.write(item_string)file.write('\n')file.close()print item_string #在控制臺輸出return item # 會在控制臺輸出原item數據,可以選擇不寫- 1
運行
依舊進入項目目錄,在終端輸入
scrapy crawl heartsong看一下輸出的信息,沒問題。
看一下生成的本地文件,也ok。
小結
本部分介紹了頁面解析的方法,下一部分將會介紹Scrapy爬取多個網頁,也是讓咱的爬蟲真正爬起來的一部分。結合這兩節,你就能將我的論壇上的所有帖子都爬下來了。
總結
以上是生活随笔為你收集整理的Scrapy定向爬虫教程(二)——提取网页内容的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: scrapy需要的xpath知识点
- 下一篇: dojo中的dojo/on