還是以簡書首頁為例(7日熱門trending/weekly/
,30日熱門trending/monthly/
網頁結構相似、樣式是一樣的),抓取 文章標題、作者、閱讀量、評論數、喜歡數和打賞。
1. 只提取文章標題內容
首先看一下 文章標題 部分的網頁代碼,對網頁結構進行分析。
a 標簽的內容就放著 文章標題。它是在一個class="content"
的div標簽下面。那么如果只想抓到文章標題進行分析的話(如分析簡書首頁熱點文章類型),就很簡單。
titles = selector.xpath('//a/text()').extract()
顯然這個是抓取到所有a標簽的文本內容,很明顯包含了頁面上所有有鏈接,不僅僅是我們需要的文章標題。
需要加以限定,限定的方式一是加上需要抓取標簽內容的樣式屬性(class
) 或者指定這個標簽的路徑(xpath進行路徑的限定,它的父標簽,或父父標簽是什么,或在這些標簽上再加屬性限制)。
titles = selector.xpath('//a[@class="title"]/text()').extract()
這樣就可以了。在頁面上class='title'
就是文章標題的樣式,注意這時候提取的是一個集合,循環迭代出來就是所有的文章標題。
titles = selector.xpath('//a[@class="title"]/text()').extract()
for title in titles:
print title
注意,這時候,我們用Chrome的“檢查” -- copy -- copy xpath,復制到的 文章標題 的xpath 是 //*[@id="note-8305658"]/div/a
,很顯然這是一篇文章標題的xpath,不能作為我們循環提取頁面上所有文章標題 的xpath。
但是可以印證 a標簽是在一個div下的,這個id 指是一個li 標簽。也就是所有我們所需要的文章信息(標題,作者、閱讀量等)都是在 li 標簽里。
那這里要提取 文章標題 還有一種寫法。
titles = selector.xpath('//div[@class="content"]/a/text()').extract()
2.提取結構化數據
結構化數據指的是一個數據塊,對應數據庫里的一條記錄,程序中的一個對象。
根據上面的分析,要提取一篇文章所有信息(標題,作者,閱讀量等),需要把循環放在 li
這里。
infos = selector.xpath('//ul[@class="note-list"]/li')
再對infos進行循環,取出 li > div > a
標簽的text就是文章標題。
infos = selector.xpath('//ul[@class="note-list"]/li')
for info in infos:
title = info.xpath('div/a/text()').extract()[0]
print title
此處要注意,在循環中使用的xpath是針對 infos 中的 info 進行一次xpath。
特別注意: infos = selector.xpath('//li[@class="have-img"]')
雖然選取的也是 li
,但是這時候迭代是取不出來所有文章的,因為 have-img
指的是那些有圖的文章標題的列表。
把完整代碼給出來。
def parse(self, response):
selector = Selector(response)
infos = selector.xpath('//ul[@class="note-list"]/li')
for info in infos:
title = info.xpath('div/a/text()').extract()[0]
print title
author = info.xpath('div/div[1]/div/a/text()').extract()[0]
print author
注意:在循環中直接使用了數組下標[0]
的方式就是提取所要的一行內容。
一個小技巧,這時候最好用的是Chrome中的copy xpath, 比如作者,copy出來的是
//*[@id="note-8305658"]/div/div[1]/div/a
你應該直接在代碼中直接寫id后面的那個路徑。
3.總結一下
抓取結構化數據的關鍵,首先對網頁結構要熟悉了解,另外就是要選擇循環點,一般是父標簽到數據塊所在的標簽,第三就是結合使用Chrome的copy xpath很方便,可以提高效率。