Xpath中选取到相同属性节点,但是只要第一个属性怎么做

刚学爬虫,也没看具体的文档,所以遇到这个问题多试了几次,记录下。

 

爬取豆瓣电影Top250,用Xpath很方便直观,在选取节点中,电影的名称节点有相同的两个属性:

 <span class="title">肖申克的救赎</span>
 <span class="title">&nbsp;/&nbsp;The Shawshank Redemption</span>
 <span class="other">&nbsp;/&nbsp;月黑高飞(港)  /  刺激1995(台)</span>

比如上面的前两个,class="title",但是我只想要第一个电影名称。

我先这么做:

url = 'https://movie.douban.com/top250'
html = etree.HTML(get_one_page(url)) 注:get_one_page(url)是单独编写的爬取网页获得html文档的函数
results = html.xpath('//ol//div/div[@class="info"]//a/span[@class="title"]/text()')
for result in results:
print(result)

得到的结果是:

肖申克的救赎
 / The Shawshank Redemption
霸王别姬
这个杀手不太冷
 / Léon
阿甘正传
 / Forrest Gump

 ...

 

后来想到美丽汤会只会选择第一个匹配的节点:

url = 'https://movie.douban.com/top250'
html = etree.HTML(get_one_page(url))
results = html.xpath('//ol//div/div[@class="info"]//a/span[@class="title"]')
for result in results:
name = BeautifulSoup(etree.tostring(result), 'lxml')
print(name.span.string)

初次这么写,得到的结果还是跟上面一样,Xpath选择中不能到span节点,改一下,只选到a节点:

url = 'https://movie.douban.com/top250'
html = etree.HTML(get_one_page(url))
results = html.xpath('//ol//div/div[@class="info"]//a')
for result in results:
name = BeautifulSoup(etree.tostring(result), 'lxml')
print(name.span.string)

这么着就得到了纯中文的电影名称:

肖申克的救赎
霸王别姬
这个杀手不太冷
阿甘正传
美丽人生
泰坦尼克号
千与千寻

这时突然觉得Xpath选择中肯定有一个简单的方法可以选择某一个节点,而且就是下标,果不其然。

url = 'https://movie.douban.com/top250'
html = etree.HTML(get_one_page(url))
results = html.xpath('//ol//div/div[@class="info"]//a/span[@class="title"][1]/text()')
for result in results:
print(result)

下标从1开始,改为2得到:

/ The Shawshank Redemption
 / Léon
 / Forrest Gump
 / La vita è bella
 / Titanic

...

在此过程中还遇到一个问题,之前得到电影名称用有非中文的名称,装进了一个表,

name = ['肖申克的救赎', '\xa0/\xa0The Shawshank Redemption', '霸王别姬', '这个杀手不太冷', '\xa0/\xa0Léon', '阿甘正传', '\xa0/\xa0Forrest Gump', '美丽人生', '\xa0/\xa0La vita è bella']

这里面有'\xa0'的字符,查看网上的说法是:该字符是不间断空格符。我们通常所用的空格是 \x20 ,是在标准ASCII可见字符 0x20~0x7e 范围内。而 \xa0 属于 latin1 (ISO/IEC_8859-1)中的扩展字符集字符,代表空白符nbsp(non-breaking space)(如开头HTML文本中第三行的显示)。 latin1 字符集向下兼容 ASCII ( 0x20~0x7e )。

 

当时没有解决爬取的时候筛选的问题,想着直接在这个列表了去掉,弄了个正则表达式。

pattern = re.compile(r'^\xa0/\xa0.*?')

for i in name:
if re.match(pattern, i):
name.remove(i)
continue

print(name)

name = ['肖申克的救赎',  '霸王别姬', '这个杀手不太冷', '阿甘正传',  '美丽人生']

 

转载于:https://www.cnblogs.com/baijinyipin/p/10669981.html

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值