赞
踩
02 信息提取
明白了HTML文档的标记思路,想要在这种文档中提取关键信息也就有3种策略了。第 1 种,暴力搜索。说到底毕竟是个文档,只不过多了标签信息,所以无视标签强行搜索并不难,但是搜索结果可能需要再处理。
第 2 种,解析文档得到树状结构再进行关键信息提取。这种方法要搞明白文档结构,相当于先做复杂工作,最后的输出是简洁的。
实践中通常从问题出发,方便哪个就用哪个,下面简单介绍bs4库的信息提取工具以及正则表达式。
bs4库的HTML解析器
soup=BeautifulSoup('data','html.parser')
它构造一个soup对象,将HTML文档以“标签树”的形式组织起来,在这个具有层级关系的“标签树”中,基本元素就是标签,用它可以解析到任意标签的名称、属性、内容字符串等。bs4库的查找方法
<>.find_all(name, attres, recursive, string, **kwargs)
返回值:列表类型,存储查找的结果
name:标签名称的检索字符串、正则表达式、列表、方法或True
attrs:标签属性值的检索字符串、正则表达式、列表或True
(常用attrs={‘属性1’: ‘值1’, ‘属性2’: ‘值2’,...})
recursive:是否对子孙全部检索,默认True
string:标签中字符串区域的检索字符串
findall使用起来非常灵活,具体的使用方法和注意事项还需要查阅说明文档,网络上也有很多用法总结类的文章。
正则表达式和re库
正则表达式是一种用来简洁描述字符串特征的工具。 这个其实有点信息压缩的感觉,比如字符串‘899999999’可以描述成‘8,9个9’,是不是简洁许多呢!但是它远比这个例子复杂,因为它定义了不常用的字符和操作规则,但是如果使用恰当,确实有一行胜千言的效果。正则表达式常用操作符 | ||
操作符 | 说明 | 示例 |
. | 表示任何单个字符 | |
\d | 表示一个数字 | 等价于[0-9] |
\w | 表示一个单词 | 等价于[A-Za-z0-9] |
[ ] | 字符集,单个字符的取值范围 | [abc]表示a、b、c [a-z]表示a到z的单字符 |
[^ ] | 非字符集,单个字符的排除范围 | [^abc]表示非a或b或c的单字符 |
* | 扩展0次或无限次 | abc*表示ab、abc、abcc等 |
+ | 扩展1次或无限次 | abc+表示abc、abcc、abccc等 |
? | 扩展0次或1次 | abc+表示ab、abc等 |
{m} | 扩展m次 | ab{2}c表示abbc |
{m,n} | 扩展m至n次(含n) | ab{1,2}c表示abc、abbc |
^ | 匹配字符串开头 | ^abc表示abc开头的字符串 |
$ | 匹配字符串结尾 | abc$表示abc结尾的字符串 |
| | 左右表达式任意一个 | (abc | def)表示abc、def |
( ) | 分组标记,内部只能使用 | | (abc)表示abc |
经典实例 | 说明 | |
^[A‐Za‐z]+$ | 由26个字母组成的字符串 | |
^[A‐Za‐z0‐9]+$ | 由26个字母和数字组成的字符串 | |
^‐?\d+$ | 整数形式的字符串 | |
^[0‐9]*[1‐9][0‐9]*$ | 正整数形式的字符串 | |
[\u4e00‐\u9fa5] | 匹配中文字符 | |
[1‐9]\d{5} | 境内邮政编码,6位 | |
\d{3}‐\d{8}|\d{4}‐\d{7} | 电话号码,010‐68913536 |
前面我们已经将网页的HTML文档抓取下来,接下来我们增加信息提取的代码来实现上面说的一些功能。
上一期获取了的无序列表ul标签,它里面包含一些列表li标签,列表标签元素的id属性和内容结构是类似的,所以基本思路是可以根据这个id过滤出这个标签列表,进一步遍历提取一个列表元素内的文本,再用正则表达式配合字符串处理进行提取即可。
ul标签内的li标签
上期ul标签的输出 每个列表元素提取出来的文本加入信息提取代码后的最终输出
上述输出的源代码from bs4 import BeautifulSoup #bs4约定的引用方式import requests #提交网络请求所需要的库import reimport time #用来处理时间戳#要访问的资源地址,从浏览器中复制过来url="https://weixin.sogou.com/weixin?type=1&s_from=input&query=%E6%94%BE%E7%96%97&ie=utf8&_sug_=y&_sug_type_=&w=01019900&sut=5917&sst0=1600786021035&lkt=0%2C0%2C0"#在请求头中构造和浏览器一样的用户代理,同样从浏览器中复制过来headers={ 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36' }#发起get请求时加入上面的headers,忽悠反爬虫这是个来自浏览器的请求r=requests.get(url,headers=headers)#这里得到HTML文档内容demo=r.text#bs4的html解析器Bigsoup=BeautifulSoup(demo,'html.parser')#在Bigsoup中提取所关注的标签,缩小查找范围taglist=Bigsoup.findAll(id=re.compile(r'sogou_vr_11002301_box_\d'))#遍历上面的标签列表,每个标签处理方法是一样的for tag in taglist: #将每个小标签解析成smallsoup,再提取该标签内的所有文本 smallsoup=BeautifulSoup(str(tag),'html.parser') txt=smallsoup.text #使用各种信息提取手段提取关键信息 name=txt[7:].split('\n',1)[0]#字符串切片和分割 id=re.findall(r'微信号:[0-9a-zA-Z_]+',txt.replace('\n','')) title=re.findall(r'最近文章:[\u4e00-\u9fa5]+',txt.replace('\n','')) timestamps=re.findall(r"\d{9}",txt)#这里是获取的时间戳字符串 if len(timestamp)==1: #将时间戳字符串转换成格式化的时间 Time=time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(int(timestamps[0]))) #接下来就可以输出啦 print('{}.'.format(n),name,id[0]) if len(title)==1: print(title[0]) print('发布时间:',Time)
这样,一个网页上的关键信息就被爬虫抓取下来了,python代码是不是相当简洁呢!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。