关于数据提取的四个主流方法就回顾完了,当然不用也不必全会。我个人认为正则是一定要OK的,其余三个拣一个上手即可。剩下部分,总得达到“开书了然”的境界吧。毕竟说不定什么时候就需要阅览别人的代码,你怎么管得找人家用xpath呢还是用PyQuery呢?
这是最后一次在句子迷实战,此次目标书籍:《年华是无效信》——是我钟爱!
from pyquery import PyQuery as pq
doc = pq(html)
pq(url="")
直接获取网页(不建议,没有隐藏爬虫信息吧) pq(filename="")
针对本地文件<html><head><title>The Dormouse's storytitle>title>head>head>
<body>
<p class="title"><b>The Dormouse's storyb>b>p>p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1">Elsiea>a>,
<a href="http://example.com/lacie" class="sister" id="link2">Laciea>a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tilliea>a>;
and they lived at the bottom of a well.p>p>
<p class="story">...p>p>
下面,仍用之前使用过的残缺的爱丽丝文档演示
doc("p")
直接选择p标签doc(".title")
通过类名选择标签doc("#link1")
通过id名选择标签 doc("body .story #link3")
表示body标签下class为story的标签、下的id为link3的标签 如果通过标签寻找返回太多,需要标签中其他属性值来精确定位,可以参数里多个值,中间不需要空格doc("a.sister#link2")
(为什么我只返回两个?因为之前忘了,现在才加的,而我已经移除了id=#link1的标签了)
children()
返回子标签,且只返回子标签(不管孙子标签)parent()
返回父标签,parents()
返回父级以上标签siblings()
返回兄弟标签上述操作之后拿到的是由对象组成的列表,现在我们要对它进一步操作
doc.(".title").html()
class为title的标签下的内容 doc("#link1").attr("href")
或者doc("#link1".attr.href)
doc("#link1").attr("href", "baidu.com")
doc("#link1").remove()
doc("#link2").text()
doc("#link2").addClass()
/doc("#link2").removeClass()
为了更精确定位元素,还有以下操作
1. doc("p:first-child")
定位第一个p标签
2. doc("p:last-child")
定位第最后一个p标签
3. doc("p:gt(2)")
定位索引大于2的p标签(从0开始计数)
4. doc("p:nth-child(2)")
定位第二个p标签
5. doc("p:nth-child(2n)")
定位索引为偶数的p标签
6. doc("p:contains(story)")
定位文本信息中有“story”的p标签
区别于BeautifulSoup,我们拿到返回列表之后,不能单纯的使用列表的索引方式取出列表中的对象进行操作,这样返回的是字符串类型,需要用eq()
网址目标:句子迷。
def parse_html(html):
data = {}
doc = pq(html)
sentences = doc(".xlistju")
loveds = doc(".views-field-ops a.flag-action")
comments = doc(".comment-link")
# 对于这种查找结果直接返回列表,最好保存数据前打印各自的长度
# 网页中可能出现class值相同,但不是需要的标签
with open("Invalid_letter.txt", "a", encoding="utf-8") as ob:
for i in range(len(sentences)):
data["sentence"] = sentences.eq(i).text()
data["loved"] = loveds.eq(i).text()
data["comment"] = comments.eq(i).text()
ob.write(json.dumps(data, ensure_ascii=False))
ob.write("\n")
完整代码已经上传GitHub,包括前面使用xpth,”美丽汤”,正则的实战案例,放在一起可以比较四个优劣。