Python爬虫网页,解析工具lxml.html(二)
【前情回顾】如何灵活的解析网页,提取我们想要的数据,是我们写爬虫时非常关心和需要解决的问题。
从Python的众多的可利用工具中,我们选择了lxml的,它的好我们知道,它的妙待我们探讨。前面我们已经从HTML字符串转换成的HtmlElement对象,接下来我们就探讨该如何操作这个的HtmlElement对象。
lxml.html的HtmlElement对象的各种属性和方法
这个的HtmlElement对象有各种方法,我们重点讨论跟解析网页相关的函数,而修改这个对象的方法若与提取内容相关也一并介绍,介绍过程结合下面这段HTML代码以便更好说明问题:
<divclass="post"id="123"><pclass="para">abc<ahref="/to-go">link</a></p></div>.attrib属性和.get()方法
前者是html tag的属性集合,以字典表示;后者是取得某个属性的值,相当于字典的.get()方法。看示例:
In[35]:doc=lxml.html.fromstring('<divclass="post"id="123"><pclass="para">abc<ahref="/to-go">link</a></p></div>')In[37]:doc.attribOut[37]:{'class':'post','id':'123'}In[38]:doc.get('class')Out[38]:'post'.drop_tag()方法
移除该html标签,但保留它的子节点和文本并合并到该标签的父节点。
In[46]:doc=lxml.html.fromstring('<divclass="post"id="123"><pclass="para">abc<ahref="/to-go">link</a></p></div>')In[47]:doc.find('.//p').drop_tag()In[48]:lxml.html.tostring(doc)Out[48]:b'<divclass="post"id="123">abc<ahref="/to-go">link</a></div>'.drop_tree()方法
移除该节及其子节点和文本,而它后面的文本(尾文)合并到前面一个节点或父节点。
In[50]:doc=lxml.html.fromstring('<divclass="post"id="123"><pclass="para">abc<ahref="/to-go">link</a></p></div>')In[51]:doc.find('.//p').drop_tree()In[52]:lxml.html.tostring(doc)Out[52]:b'<divclass="post"id="123"></div>'.find(path),. find(path),. findtext(path)方法
通过路径(Xpath的)或标签查找特定节点,前者返回找到的第一个,第二个返回找到的全部HTML元素,第三个返回找到的第一个的节点的文本(的.text)
In[55]:doc=lxml.html.fromstring('<divclass="post"id="123"><pclass="para">abc<ahref="/to-go">link</a></p></div>')In[56]:doc.find('p')Out[56]:<Elementpat0x7fc40a4dd6d8>In[57]:doc.find('.//a')Out[57]:<Elementaat0x7fc409fee4a8>In[58]:doc.findall('p')Out[58]:[<Elementpat0x7fc40a4dd6d8>]In[76]:doc.findtext('.//a')Out[76]:'link'.find_class(CLASS_NAME)方法
通过类名称查找所有含有CLASS_NAME的元素,返回的HtmlElement的列表
In[70]:doc=lxml.html.fromstring('<divclass="post"id="123"><pclass="para">abc<ahref="/to-go">link</a></p><pclass="parap2"></p></div>')In[71]:doc.find_class('para')Out[71]:[<Elementpat0x7fc40a3ff278>,<Elementpat0x7fc40a3ffc78>].get_element_by_id(id)方法
得到第一个ID为输入ID的节点。如果有多个相同ID的节点(按道理讲,一个HTML文档里面的ID是唯一的)只返回第一个。
In[79]:doc=lxml.html.fromstring('<divclass="post"id="123"><pclass="para">abc<ahref="/to-go">link</a></p></div>')In[80]:doc.get_element_by_id('123')Out[80]:<Elementdivat0x7fc409fda2c8>.getchildren(),getparent()方法
顾名思义,获得孩子节点和父节点。需要注意的是,还是可以有多个(返回列表),父亲只有一个。
In[83]:doc=lxml.html.fromstring('<divclass="post"id="123"><pclass="para">abc<ahref="/to-go">link</a></p></div>')In[84]:doc.getchildren()Out[84]:[<Elementpat0x7fc410836b38>]In[85]:doc.getparent()Out[85]:<Elementbodyat0x7fc40a3ff9a8>#注意:输入的本没有body,div已经是最上层节点,它的父节点就是body了.getnext()。getprevious()方法
获取后一个或前一个节点,如果没有则返回无。
In[109]:doc=lxml.html.fromstring('<div><p>abc</p><p>xyz</p></div>')In[110]:doc.getnext()In[111]:doc.find('p').getnext()Out[111]:<Elementpat0x7fc409fdad68>In[112]:doc.find('p').getprevious().getiterator(),. iter()方法
从该节点开始,按文档顺序(深度优先)遍历所有子节点。可以指定只遍历某些标签。
In[127]:doc=lxml.html.fromstring('<divclass="post"id="123"><pclass="para">abc<ahref="/to-go">link</a></p></div>')In[128]:foritrindoc.getiterator():...:print(itr.tag)...:divpaIn[129]:foritrindoc.iter():...:print(itr.tag)...:divpa.iterchildren()方法
只遍历子节点。
.iterancestors()。iterdescendants()方法前者遍历前辈(从父亲节点开始),后者遍历后辈(从子辈开始),都跳过该节点。
In[134]:doc=lxml.html.fromstring('<divclass="post"id="123"><pclass="para">abc<ahref="/to-go">link</a></p></div>')In[135]:a=doc.find('.//a')In[136]:foritrindoc.iterancestors():...:print(itr.tag)...:bodyhtmlIn[137]:foritrina.iterancestors():...:print(itr.tag)...:pdivbodyhtmlIn[138]:foritrindoc.iterdescendants():...:print(itr.tag)...:pa.iterfind(path)方法
遍历所有符合路径的子节点,类似于的findall()
.make_links_absolute(BASE_URL)很多网页的链接都是类似HREF =” /路径/ a.html”没有写全网址,这个方法的作用就是补全网址。
.tag属性该节点的html标签名称
.text .tail属性都是该节点的文本内容,不同的是一个在标签内,一个在尾部:
<p>text</p>tail
再看下面的代码
In[173]:doc=lxml.html.fromstring('<div><pclass="para">abc<ahref="/to-go">link</a>worod</p>apple</div>')In[174]:p=doc.find('p')In[175]:p.textOut[175]:'abc'In[176]:p.tailOut[176]:'apple'.text_content()方法
返回给节点及其子节点包含的所有文本
In[178]:doc.text_content()Out[178]:'abclinkworodapple'
以上就是我们从网页提取内容时用到的主要属性和方法。下一节,我们将以实例讲解具体提取数据的过程。
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。