如何用scrapy提取不在標籤內的文字?

我在練慣用scrapy爬豆瓣圖書top250,想把每本書的書名、作者和出版年提取出來,可是如圖所示,出版年、頁數、定價、ISBN這幾個數據不在任何標籤內,怎麼用xpath或別的方法提取出來呢?不在scrapy框架里又有什麼提取方法呢?


response.xpath(u"//span[./text()="出版社:"]/following::text()[1]")

如果text() 中有空格, 感謝 @董成良 提醒, 你可能還需要這麼寫

response.xpath(u"//span[contains(./text(), "出版社:")]/following::text()[1]")

或者全匹配:

response.xpath(u"//span[.//text()[normalize-space(.)="出版社:"]]/following::text()[1]")

這就是我不喜歡xpath的原因,在pyquery中, 你只需要

response.doc(u"span:contains("出版社:")")[0].tail


推薦用正則,結果如圖。

import urllib2
import re

def parse(s):
c = re.compile(r"&(.*?):& (.*?)&
", re.M)
print c.findall(s)

if __name__ == "__main__":
url = "http://book.douban.com/subject/3833024"
resp = urllib2.urlopen(url)
parse(resp.read())
resp.close()

如果用xpath,chrome里有個小技巧。


xpath表達式後加/text(),例如 /span/text()


你好,請問你的問題解決了嗎?最後怎麼做到的?因為我用scrapy也遇到了類似的問題,如果提取text()在csv表中就會有半形逗號,如果全部提取子標籤就會把&裡面的內容也取出來。要怎麼做能夠只提取&標籤外的內容呢?


謝邀。
可以提取父節點的文字,從圖片上看貌似是個div標籤,用getText(),得到所有文字,然後再對文字處理,比如取後13位對應ISBN號


謝邀,受寵若驚,誠惶誠恐,然並卵,我只會簡單用beautifulsoup4,可以用找到文字前的標籤,然後用nextSibling找到這個文字。
tr = soup.find("div", {"id" : "info"})
spans = tr.find_all("span", {"class" : "pl"})
for span in spans:
print span.contents[0] #span標籤內的內容
print span.nextSibling.string #span後面緊跟著的內容


邀請我?我不會python啊,會用R爬數據。那我就用R寫回答一下。
# douban scraping
library(rvest)
library(magrittr)
library(stringr)
douban.top250book &<- function(pgnum){
#pgnum &<- 0
url &<- paste0("豆瓣圖書 Top250",pgnum)
book.name &<- url%&>%html_session()%&>%html_nodes("div.pl2 a")%&>%html_text()%&>%gsub("
","",.)%&>%gsub(" ","",.)
http://book.publish.info &<- url%&>%html_session()%&>%html_nodes("p.pl")%&>%html_text()
return(data.frame(book.name=book.name,book.publish.info=http://book.publish.info))
}
#以上是封裝個爬一個頁面的函數
ser &<- c(0:9)*25 #共10頁,翻了翻頁,看到URL的pgnum變化為0,25,50,於是找到規律
res.final&<- data.frame()
# 下面是一個顯示循環,效率不高。但是抓10頁東西,我也就不寫多線程了。
for(m in ser){
res.final &<- rbind(douban.top250book(m),res.final)
}
dim(res.final)
# 250 行,2列
#至於分離出版社,出版年份,價格這些東西,你在excel裡面按照/進行分列就可以搞定了。
#我上面嫌麻煩沒寫正則幫你直接提取。
對R感興趣,歡迎交流!我的博客龍君蛋君 - 博客園
下面是爬出來的數據示例。
book.name http://book.publish.info
1 世界盡頭與冷酷仙境 [日] 村上春樹 / 林少華 / 上海譯文出版社 / 2002-12 / 23.00元
2 烏合之眾:大眾心理研究 (法)古斯塔夫.勒龐 / 馮克利 / 中央編譯出版社 / 1998-01 / 16.00元
3 秘密 [澳] 朗達·拜恩 / 謝明憲 / 中國城市出版社 / 2008-11 / 32.00
4 生活在別處 [捷克] 米蘭·昆德拉 / 袁筱一 / 上海譯文出版社 / 2004-5 / 25.00元
5 世界因你不同:李開復自傳 李開復 / 中信出版社 / 2009 / 29.80元
6 傲慢與偏見 [英] 奧斯丁 / 王科一 / 上海譯文出版社 / 1996-12 / 11.00元


受寵若驚的謝邀,不過我並不會……


def parse(self,response):
states = {}
list1 = []
list2 = []

for row in response.xpath("//*[@id="info"]/*"):
if row.xpath("span[@class="pl"]/text()"):
title = row.xpath("span[@class="pl"]/text()").extract()[0].strip()
text = row.xpath("a/text()").extract()[0].strip()
states[title]=text
elif row.xpath("text()"):
list1.append(row.xpath("text()").extract()[0].strip()[:-1])

for row in response.xpath("//*[@id="info"]/text()").extract():
if row.strip():
list2.append(row.strip())

for i in range(len(list1)):
states[list1[i]]=list2[i]

for n in states:
print n,states[n]

不建議用正則,scrapy能不用正則盡量不用,這樣提取就行,到上一層DIV用TEXT()即可取出所有文字,我寫了個大概的,試了下可以跑,字典key是類名,value是內容。
方法有點蠢,URL形式的類名和文本一次取的,然後標籤外的是分開取的,放到兩個列表裡,再統一塞到字典里。


謝邀,你可以先抓大再抓小。比如,你可以把下面這一段數據先抓下來,然後再用正則表達式匹配,這樣也很快。

還有就是通過response.xpath.(" //*[@id="info"]/text() ").extract() 可以把
text
這個區域的文本全部找出來。你所需要的信息都在裡面,你試試看


用beautifulsoup庫,獲取書本HTML區域的div的soup。
用.text提取div的所有文本信息
用.split("/r")或者是/n,兩者選一,來分割文本儲存成list數組序列。這時候書本各行信息基本都劃分成元素在list了。
想獲取其中任意,可以這樣,以提取年份為例
for each in list
if "出版年" in each
那麼就提取。

我用這種方式做了爬蟲,遞歸地爬豆瓣用戶讀過的書本信息,自動生成markdown格式的書本信息文件,平時書荒就在爬蟲里找書看,效果不錯。


推薦閱讀:

tcp 編程中,connect 連接成功的標準是什麼?
tcp連接的問題?
前途未卜的准程序員,吃過苦頭有智慧的或者過來人前輩大牛有什麼樣的忠告給當局者?
金融工程的新生怎麼選購筆記本電腦?
浙大的計算機和電氣從就業來看選哪個好?

TAG:程序員 | Python | 編程 | 爬蟲計算機網路 | scrapy |