【问题标题】:Python's "re" module not working?Python的“re”模块不起作用?
【发布时间】:2013-07-21 20:38:46
【问题描述】:

我正在使用 Python 的“re”模块如下:

request = get("http://www.allmusic.com/album/warning-mw0000106792")
print re.findall('<hgroup>(.*?)</hgroup>', request)

我所做的只是获取this site 的 HTML,并寻找这段特殊的 sn-p 代码:

<hgroup>
    <h3 class="album-artist">
        <a href="http://www.allmusic.com/artist/green-day-mn0000154544">Green Day</a>        </h3>

    <h2 class="album-title">
        Warning        </h2>
</hgroup>

但是,它继续打印一个空数组。为什么是这样?为什么re.findall 找不到这个sn-p?

【问题讨论】:

  • &lt;hgroup&gt;&lt;hgroup&gt;&lt;/hgroup&gt;&lt;/hgroup&gt; 怎么样?那应该匹配什么?

标签: python string get


【解决方案1】:

您正在解析的 HTML 位于多行中。您需要像这样将re.DOTALL 标志传递给findall

print re.findall('<hgroup>(.*?)</hgroup>', request, re.DOTALL)

这允许. 匹配换行符,并返回正确的输出。

@jsalonen 是对的,当然,用正则表达式解析 HTML 是一个棘手的问题。但是,在这样的小情况下,尤其是一次性脚本,我会说这是可以接受的。

【讨论】:

  • 说真的,伙计们。 HTML的正则表达式?它可能工作一两次,但最终你一定会失败:正则表达式适用于正则语言,而 HTML 不是。
  • @jsalonen,对于 html 的子集很好。例如,请参阅您链接的第二个答案
  • 有时它可能会起作用,但它确实是非常糟糕的工程实践。此外,使用实际的 HTML 解析器同样简单。那么为什么不这样做呢?
  • @Sim 我忘了你还需要DOTALL 标志来让. 匹配\n。我已经更新了我的答案。再想一想,你实际上并不需要MULTILINE。我的错。
  • @NolenRoyalty 我绝对明白你的意思:在快速解决问题时,显然不要将时间浪费在过度设计上。我要争辩的是,正则表达式甚至没有那么容易。使用好的 HTML 解析器,总行数与 hacky regexp 解决方案没有太大区别。
【解决方案2】:

re 模块没有损坏。您可能会遇到的事实是,并非所有 HTML 都不能轻松地与简单的正则表达式匹配。

请尝试使用实际的 HTML 解析器(如 BeautifulSoup)解析您的 HTML:

from BeautifulSoup import BeautifulSoup
from requests import get

request = get("http://www.allmusic.com/album/warning-mw0000106792")
soup = BeautifulSoup(request.content)
print soup.findAll('hgroup')

或者,pyquery:

from pyquery import PyQuery as pq

d = pq(url='http://www.allmusic.com/album/warning-mw0000106792')
print d('hgroup')

【讨论】:

  • 出于某种原因,我记得BeautifulSoup 付出了比这更多的努力。这可能只是我当时使用它的经验不足。我对这个解决方案的简单程度感到惊讶。 +1
猜你喜欢
  • 2014-01-31
  • 1970-01-01
  • 2010-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多