1 目标

目标网址(丁香园论坛):http://www.dxy.cn/bbs/thread/626626#626626
目标:提取第一个回复的所有内容,如下图所示:
在这里插入图片描述

2. 实战说明

2.1 前期代码准备

import requests # 导入报错的朋友手动安装一下pip install requests
from lxml import etree # 导入报错的朋友手动安装一下pip install lxml

# get_html_text(url)获取网页信息
def get_html_text(url):
    try:
        r = requests.get(url) # 爬取完整的网页数据
        r.raise_for_status() # 如果状态不是200,引发HTTPError异常
        return r.text # 以字符串的形式返回爬取的网页内容
    except:
        print("访问出错")
        return "" # 发生异常,返回空字符串

url = 'http://www.dxy.cn/bbs/thread/626626#626626'
data = get_html_text(url)
# 做好ElementTree
tree = etree.HTML(data)
# 以列表形式,返回所有包含所需信息的td标签
ls = tree.xpath('//td[@class="postbody"]')

n = len(ls) # 统计ls里面有几个元素
print('取到的td标签数:{}'.format(n)) # 输出是4,因为未登录只能抓到4条记录
# 因为第一条是问题,所以第二条才是第一个回复,因此用ls[1]取到
# 下面就是测试语句,展示text()和string的区别了

2.2 text()方法

text()又有两种用法,一种是ls[1].xpath(’./text()’),一种是ls[1].xpath(’.//text()’)。

2.2.1 ls[1].xpath(’./text()’)用法

表示只取当前节点中的文本内容,对于子孙节点的内容不会取。
测试代码:

print('输出取到的文本数目:', end='')
print(len(ls[1].xpath('./text()')))
# 输出取到的文本列表
print("处理前:")
print(ls[1].xpath('./text()'))
# 把列表中的元素合成一个字符串,同时清理组合字符串两端的空格和换行符
print("处理后:")
print('\n'.join(ls[1].xpath('./text()')).strip())

输出结果:

取到的td标签数:4
输出取到的文本数目:4
处理前:
['\n \n 从发作的症状上比较符合血管迷走神经性晕厥,直立倾斜试验能协助诊断。在行直立倾斜实验前应该做常规的体格检查、ECG、UCG、holter和X-ray胸片除外器质性心脏病。', '贴一篇“口服氨酰心安和依那普利治疗血管迷走性晕厥的疗效观察”', '作者:林文华 任自文 丁燕生', '\n \t ']
处理后:
从发作的症状上比较符合血管迷走神经性晕厥,直立倾斜试验能协助诊断。在行直立倾斜实验前应该做常规的体格检查、ECG、UCG、holter和X-ray胸片除外器质性心脏病。
贴一篇“口服氨酰心安和依那普利治疗血管迷走性晕厥的疗效观察”
作者:林文华 任自文 丁燕生

在这里插入图片描述

我们发现:td标签的子标签a中的文本内容"http://www.ccheart.com.cn/ccheart_site/Templates/jieru/200011/1-1.htm"没有被提取出来。

2.2.2 ls[1].xpath(’.//text()’)用法

表示取当前节点及其子孙节点中的文本内容。
测试代码:

print('输出取到的文本数目:', end='')
print(len(ls[1].xpath('.//text()')))
# 输出取到的文本列表
print("处理前:")
print(ls[1].xpath('.//text()'))
# 把列表中的元素合成一个字符串,同时清理组合字符串两端的空格和换行符
print("处理后:")
print('\n'.join(ls[1].xpath('.//text()')).strip())

结果输出:

取到的td标签数:4
输出取到的文本数目:5
处理前:
['\n \n 从发作的症状上比较符合血管迷走神经性晕厥,直立倾斜试验能协助诊断。在行直立倾斜实验前应该做常规的体格检查、ECG、UCG、holter和X-ray胸片除外器质性心脏病。', '贴一篇“口服氨酰心安和依那普利治疗血管迷走性晕厥的疗效观察”', '作者:林文华 任自文 丁燕生', 'http://www.ccheart.com.cn/ccheart_site/Templates/jieru/200011/1-1.htm', '\n \t ']
处理后:
从发作的症状上比较符合血管迷走神经性晕厥,直立倾斜试验能协助诊断。在行直立倾斜实验前应该做常规的体格检查、ECG、UCG、holter和X-ray胸片除外器质性心脏病。
贴一篇“口服氨酰心安和依那普利治疗血管迷走性晕厥的疗效观察”
作者:林文华 任自文 丁燕生
http://www.ccheart.com.cn/ccheart_site/Templates/jieru/200011/1-1.htm

我们看到输出取到的文本数目:5,之前是4,就是因为把字标签a标签中的文本“http://www.ccheart.com.cn/ccheart_site/Templates/jieru/200011/1-1.htm”取到了。

2.3 string()方法

string()会把当前节点和所有的子孙节点中的文本全部提取出来,组合成一个字符串。
测试代码:

print('输出取到的文本数目:', end='')
print(len(ls[1].xpath('string(.)')))
# 输出取到的文本列表
print("处理前:")
print(ls[1].xpath('string(.)'))
# 把列表中的元素合成一个字符串,同时清理组合字符串两端的空格和换行符
print("处理后:")
print(ls[1].xpath('string(.)').strip())

输出结果

取到的td标签数:4
输出取到的文本数目:648
处理前:

                                                                                                                                   
                                                                                                    从发作的症状上比较符合血管迷走神经性晕厥,直立倾斜试验能协助诊断。在行直立倾斜实验前应该做常规的体格检查、ECG、UCG、holter和X-ray胸片除外器质性心脏病。贴一篇“口服氨酰心安和依那普利治疗血管迷走性晕厥的疗效观察”作者:林文华 任自文 丁燕生http://www.ccheart.com.cn/ccheart_site/Templates/jieru/200011/1-1.htm
                                                                                                                                                                                                                                
处理后:
从发作的症状上比较符合血管迷走神经性晕厥,直立倾斜试验能协助诊断。在行直立倾斜实验前应该做常规的体格检查、ECG、UCG、holter和X-ray胸片除外器质性心脏病。贴一篇“口服氨酰心安和依那普利治疗血管迷走性晕厥的疗效观察”作者:林文华 任自文 丁燕生http://www.ccheart.com.cn/ccheart_site/Templates/jieru/200011/1-1.htm

分析结果发现输出的效果没有text()优雅,跟网页预览有差距,连接不同节点的字符串没有加换行符。不过提取的还是很靠谱的。

3. 总结用法

个人感觉string()不够优雅,有点坑,非要写成string(.)的形式,而且还不能在一开始的路径中写,比如:ls = tree.xpath(’//td[@class=“postbody”]/string(.)’)就会报错,而text()就可以。
然后对于text()用’//text()‘还是’/text()'就看你的需求了。
最后放上一波总结的核心代码,以后好直接套用:

# text()的用法
ls = tree.xpath('//td[@class="postbody"]')
'\n'.join(ls[1].xpath('.//text()')).strip()

# string()的用法
ls = tree.xpath('//td[@class="postbody"]')
ls[1].xpath('string(.)').strip()

4. 参考资料

  1. 解决:xpath取出指定多标签内所有文字text

后记:
我从本硕药学零基础转行计算机,自学路上,走过很多弯路,也庆幸自己喜欢记笔记,把知识点进行总结,帮助自己成功实现转行。
2020下半年进入职场,深感自己的不足,所以2021年给自己定了个计划,每日学一技,日积月累,厚积薄发。
如果你想和我一起交流学习,欢迎大家关注我的微信公众号每日学一技,扫描下方二维码或者搜索每日学一技关注。
这个公众号主要是分享和记录自己每日的技术学习,不定期整理子类分享,主要涉及 C – > Python – > Java,计算机基础知识,机器学习,职场技能等,简单说就是一句话,成长的见证!
每日学一技

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐