Python 2.7
Pycharm 5.0.3
問題
再寫一個markdown自動引用的小腳本的時候新出現的問題,也就是利用xpath取出字符串的問題,記錄一下
取出如下字符串
這里寫圖片描述
我要取出mrlevo520的內容,怎么取呢,很多方法,bs4也可以,正則也可以,動態selenium也可以,這次我想嘗試用xpath來做,一則是為了和selenium接軌,xpath的確很強大,二來是firefox提供firebug插件,可以直接定位你需要內容的標簽,一步到位簡直完美,不多說,上程序。
import urllib2
from lxml import etree
crawl_url = "http://www.lxweimin.com/p/e2c4ebd2eeb3"
req = urllib2.Request(crawl_url)
req.add_header('User-Agent','Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36')
response = urllib2.urlopen(req)
html = response.read()
selector = etree.HTML(html)
# 核心部分
bloger = selector.xpath("http://a[@class='author-name blue-link']")
info = bloger[0].xpath('string(.)').encode('utf-8').strip()
print info #打印出mrlevo
網上的方法
這里寫圖片描述
ok,我們來試下,用小哥改進的方法取出上面那個標簽
# 修改-核心部分,其余保持一樣
bloger = selector.xpath("http://a[@class='author-name blue-link']")
print bloger[0].xpath('string(.)').extract()[0]
ok,又報錯了
AttributeError: '_ElementStringResult' object has no attribute 'extract'
查看類型,如小哥所說,的確是list,再查看列表
print type(bloger) # list
print type(bloger[0]) #'lxml.etree._Element'
print (bloger[0]) # <Element a at 0x36e9208>
# ok,這要取出bloger[0]里面的字符串就可以了
再次修改代碼,去掉extract(),并去掉周圍空格
# 核心部分
bloger = selector.xpath("http://a[@class='author-name blue-link']")
print bloger[0].xpath('string(.)').strip()
# ok,取值成功
對于小哥的例子,取出來之后字符串片段使用連接字符串(join)就可以了(可能都不需要join,我沒試過)
總結
查閱多很博客,大家抄的抄,也不去做驗證,我相信簡書小哥是驗證過的,其余的,,,額,但是簡書小哥@向右奔跑貌似對我的例子并不成立,我也母雞了,還是自己調試,所以,希望我們能幫到你,這些方法你都可以試試。
BTW
如果對于單標簽定位足夠精確了,那么取出文本還可以用text的方法我們來看一下;
這里寫圖片描述
采用text的方法
import urllib2
from lxml import etree
crawl_url = "http://blog.chinaunix.net/uid-28266791-id-5754271.html"
req = urllib2.Request(crawl_url)
req.add_header('User-Agent','Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36')
response = urllib2.urlopen(req)
html = response.read()
selector = etree.HTML(html)
# 核心部分
bloger = selector.xpath("http://div[@class='Blog_left']/div/div/p/a")[0].text.encode('utf-8').strip()
print bloger #打印出夏寥寥
我們一般認為text的方法能夠取出一個標簽下的所有文本,其實不然,即使那個文本在其標簽下(次級標簽)想要定位范圍稍微放寬,text的方法就不再適用,也就是說,我想要取出一個一級標簽下的所有內容,如果有二級標簽,三級標簽,那么想要一下子把所有內容都取出來,只能靠string(.)的方法了