Python 使用正则表达式解析 HTML
Posted
技术标签:
【中文标题】Python 使用正则表达式解析 HTML【英文标题】:Python parsing HTML Using Regular Expressions 【发布时间】:2014-06-26 05:51:15 【问题描述】:我正在尝试浏览网站的 html 并对其进行解析,以寻找班级的最大入学人数。我尝试在 HTML 文件的每一行中检查一个子字符串,但这会尝试解析错误的行。所以我现在正在使用正则表达式。我现在有 \t\t\t\t\t\t\t<td class="odd">([0-9])|([0-9][0-9])|([0-9][0-9][0-9])<\/td>\r\n
作为我的正则表达式,但这个正则表达式匹配最大注册人数以及节号。还有另一种方法可以解决我试图从网页中提取的内容吗? HTML 代码 sn-p 如下:
<tr>
<td class="tableHeader">Section</td>
<td class="odd">001</td>
</tr>
<tr>
<td class="tableHeader">Credits</td>
<td class="even" align="left"> 4.00</td>
</tr>
<tr>
<td class="tableHeader">Title</td>
<td class="odd">Linear Algebra</td>
</tr>
<tr>
<td class="tableHeader">Campus</td>
<td class="even" align="left">University City</td>
</tr>
<tr>
<td class="tableHeader">Instructor(s)</td>
<td class="odd">Guang Yang</td>
</tr>
<tr>
<td class="tableHeader">Instruction Type</td>
<td class="even">Lecture</td>
</tr>
<tr>
<td class="tableHeader">Max Enroll</td>
<td class="odd">30</td>
</tr>
【问题讨论】:
阅读:***.com/a/1732454/3001761 不同意这个骗局,不是问是否可以用正则表达式完成,而是错误地尝试这样做。 这不是重复的。该 OP 正试图实际匹配标签名称、类名等。我只是试图以一种我没有得到节号和最大注册号的方式提取内容。我只需要获取 Max Enroll 号码的帮助。 好吧,与其坐在那里侮辱我处理这个问题的方式,不如为我指出正确的方向更有成效,不是吗? 这就是我在全大写免责声明中提供链接的原因。 I could also write it using <blink></blink> using toilet? 【参考方案1】:DO NOT PARSE HTML USING REGEXP.
为正确的工作使用正确的工具。
让我们打个比方来解释为什么它是错误的:这就像试图让5 year old 理解Hamlet,而他没有vocabulary and grammar 来理解Shakespeare's,当他会得到可以process more abstract concepts。
使用lxml
或BeautifulSoup
来执行此操作。
例如:获取所有偶数和所有赔率的列表:
>>> from lxml import etree
>>> tree = etree.HTML(your_html_text)
>>> odds = tree.xpath('//td[@class="odd"]/text()')
>>> evens = tree.xpath('//td[@class="even"]/text()')
>>> odds
['001', 'Linear Algebra', 'Guang Yang', '30']
>>> evens
[' 4.00', 'University City', 'Lecture']
编辑:
我只是想以这样一种方式提取内容,其中我没有获得部分编号和最大注册编号。我只需要获取 Max Enroll 号码的帮助。
好的,现在我得到了你想要的,所以这里是使用 lxml 的解决方案:
>>> for elt in tree.xpath('//tr'):
... if elt.xpath('td[@class="tableHeader"]')[0].text == "Max Enroll":
... elt.xpath('td[@class="odd"]|td[@class="even"]')[0].text
...
'30'
您只有最大注册人数。
使用 BeautifulSoup 会更容易一些:
>>> bs = BeautifulSoup(your_html_text)
>>> for t in bs.findAll('td', attrs='class': 'tableHeader'):
... if t.text == "Max Enroll":
... print t.findNext('td').text
'30'
【讨论】:
soup.find('td', text="Max Enroll").find_next_sibling('td').text
会更容易。
确实,虽然我在这里给出了更通用的方法,所以 OP 可以适应他的数据集。【参考方案2】:
使用专门解析html的工具,如BeautifulSoup
:
Beautiful Soup 是一个 Python 库,用于从 HTML 和 XML 文件。它与您最喜欢的解析器一起使用以提供惯用的 导航、搜索和修改解析树的方法。它 通常可以节省程序员数小时或数天的工作时间。
例如,您可以通过以下方式获得您想要的东西:
from bs4 import BeautifulSoup
data = """your html here"""
soup = BeautifulSoup(data)
print soup.find('td', text="Max Enroll").find_next_sibling('td').text
打印:
30
【讨论】:
如果我选择这种方法,我将无法很容易地将这个脚本提供给朋友们使用,因为它将使用他们(很可能)不会在他们的计算机上安装的库最初,正确吗? @heinst 好吧,BeautifulSoup
是一个可以轻松安装的第三方库。只需包含带有脚本依赖项的requirements.txt
文件并将其提供给您的朋友。【参考方案3】:
替代zmo's answer,使用BeautifulSoup
:
from bs4 import BeautifulSoup
data = """
<snipped html>
"""
soup = BeautifulSoup(data)
for tableHeaders in soup.find_all('td', class_="tableHeader"):
if tableHeaders.get_text() == "Max Enroll":
print tableHeaders.find_next_siblings('td', class_="odd")[0].get_text()
输出:
30
【讨论】:
以上是关于Python 使用正则表达式解析 HTML的主要内容,如果未能解决你的问题,请参考以下文章