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.jianshu.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("//a[@class='author-name blue-link']")
info = bloger[0].xpath('string(.)').encode('utf-8').strip()
print info #打印出mrlevo
网上的方法
这里写图片描述ok,我们来试下,用小哥改进的方法取出上面那个标签
# 修改-核心部分,其余保持一样
bloger = selector.xpath("//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("//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("//div[@class='Blog_left']/div/div/p/a")[0].text.encode('utf-8').strip()
print bloger #打印出夏寥寥
我们一般认为text的方法能够取出一个标签下的所有文本,其实不然,即使那个文本在其标签下(次级标签)想要定位范围稍微放宽,text的方法就不再适用,也就是说,我想要取出一个一级标签下的所有内容,如果有二级标签,三级标签,那么想要一下子把所有内容都取出来,只能靠string(.)的方法了
网友评论