Python中如何使用lxml库分析HTML?

写一个爬虫程序,使用 lxml.html 分析网页
遇到一个正文带图片的网页,无法正常解析

不带图片的正文部分是这样的:

<font face="宋体" size="3"><!--HTMLBUILERPART0--><DIV style="FLOAT: left"><script type="text/javascript" src="/2014newad.js"></script><br><script type="text/javascript" src="/xyoushangjiaoguanggao.js"></script><br><script type="text/javascript" src="/3youshangjiaoguanggao.js"></script></DIV>  我是文本<BR><BR> 
  我是文本<BR><BR> 
  我是文本<BR><BR> 
<!--/HTMLBUILERPART0--><br><div align="center"></div> </font>

带图片的正文部分是这样的:

<font face="宋体" size="3"><!--HTMLBUILERPART0--><DIV style="FLOAT: left"><script type="text/javascript" src="/2014newad.js"></script><br><script type="text/javascript" src="/xyoushangjiaoguanggao.js"></script><br><script type="text/javascript" src="/3youshangjiaoguanggao.js"></script></DIV>
<center><img border="0" src="zz.jpg" width="126" height="144"></center><BR><BR>
  我是文本<BR><BR> 
  我是文本<BR><BR> 
<!--/HTMLBUILERPART0--><br><div align="center"></div> </font>

中间多出了:

<center><img border="0" src="zz.jpg" width="126" height="144"></center>

解析代码为:

        body = doc.xpath("/html/body")[0]
        lines = body.xpath("//font[@face=\"宋体\" and @size=\"3\"]/*")
    context = []
    for line in lines:
        if not line.tail:
            continue
        context.append(line.tail)

    return context

代码解析不带图片的正文正常
解析带图片的正文,无法得到图片和文本节点(跟 if not line.tail 无关)


Python中如何使用lxml库分析HTML?

3 回复

用lxml解析HTML,主要用etree.HTML()etree.parse()加载文档,然后用XPath或CSS选择器提取数据。

from lxml import etree
import requests

# 获取HTML内容
url = 'https://example.com'
response = requests.get(url)
html_content = response.content

# 解析HTML
tree = etree.HTML(html_content)

# 使用XPath提取数据
# 获取所有链接
links = tree.xpath('//a/@href')
print("所有链接:", links)

# 获取特定class的元素文本
titles = tree.xpath('//h1[@class="title"]/text()')
print("标题:", titles)

# 使用CSS选择器(需要导入cssselect)
from lxml.cssselect import CSSSelector
sel = CSSSelector('div.content p')
paragraphs = sel(tree)
for p in paragraphs:
    print(p.text)

# 处理相对链接
base_url = 'https://example.com'
for link in links:
    if link.startswith('/'):
        full_url = base_url + link
        print(full_url)

关键点:

  1. etree.HTML()用于解析字符串,etree.parse()用于解析文件
  2. XPath语法://表示任意层级,@获取属性,text()获取文本
  3. CSS选择器更直观,但需要额外导入
  4. 注意处理编码问题和相对路径

用XPath还是CSS选择器看个人习惯,功能差不多。


因为这是个错误的 html,font 是 inline 元素,center 是 block 元素,lxml 在构造时会把 center 移到 font 外部。

爬虫就用 bs4 解析,方便快捷

回到顶部