【问题标题】:Why is this RegEx not finding any data?为什么这个 RegEx 没有找到任何数据?
【发布时间】:2014-07-10 00:10:24
【问题描述】:

我正在尝试解析/打印来自 twitter 的一些数据。我有一个打印推文的代码,但是当我尝试将相同的代码应用于用户名时,它似乎不起作用。我想在不使用 twitter API 的情况下做到这一点。

这是我打印推文的内容

def main():
    try:
        sourceCode = opener.open('https://twitter.com/search?f=realtime&q='\
                                 +keyWord+'&src=hash').read()
        splitSource = re.findall(r'<p class="js-tweet-text tweet-text">(.*?)</p>', sourceCode)
        print len(splitSource)
        print splitSource
        for item in splitSource:
            print '\n _____________________\n'
            print re.sub(r'<.*?>','',item)



    except Exception, e:
        print str(e)
        print 'error in main try'
        time.sleep(555)

main()

现在要打印用户名信息,我将“opener”更改为“browser”,但它仍会找到并打开页面,所以这不是问题。反正我不觉得。

def main():
    try:
        pageSource = browser.open('https://twitter.com/search?q='\
                                 +firstName+'%20'+lastName+'&src=hash&mode=users').read()
        splitSource = re.findall(r'<p class="bio ">(.*?)</p>', pageSource)
        for item in splitSource:
            print '\n'
            print re.sub(r'<.*?>','',item)
    except Exception, e:
        print str(e)
        print 'error in main try'


main()

它会打印源代码。问题似乎出在:

splitSource = re.findall(r'<p class="bio ">(.*?)</p>', pageSource)

这似乎根本找不到任何东西。这是我试图从中提取信息的来源的副本。

  <div class="content">
    <div class="stream-item-header">
      <a class="account-group js-user-profile-link" href="/BarackObama" >
        <img class="avatar js-action-profile-avatar " src="https://pbs.twimg.com/profile_images/451007105391022080/iu1f7brY_normal.png" alt="" data-user-id="813286"/>
        <strong class="fullname js-action-profile-name">Barack Obama</strong><span class="Icon Icon--verified Icon--small"><span class="u-isHiddenVisually">Verified account</span></span>
          <span class="username js-action-profile-name">@BarackObama</span>


      </a>
    </div>
      <p class="bio ">
          This account is run by Organizing for Action staff. Tweets from the President are signed -bo.
      </p>







  </div>

我觉得这个来源中发生了一些事情,阻止我获取生物信息。间距可能吗?我不知道。

【问题讨论】:

  • 使用 Twitter API,真的。 (这可能也违反了他们的 ToS。)
  • ...或者如果您必须解析 HTML,BeautifulSoup 会提供帮助:crummy.com/software/BeautifulSoup/bs4/doc
  • @RabidGorilla 不是不能强制正则表达式解析 HTML,而是 HTML 不是“常规语言”,所以“正则表达式”无法解析所有有效的 HTML 代码。
  • 好的,大家不要再否决这个问题了。它问得很好,有代码,示例数据并且格式相对较好。即使在我链接的问题中,人们也承认有时使用正则表达式来解析 HTML 是可以的,在某些情况下..

标签: python regex parsing


【解决方案1】:

As usual, don't use regex to parse HTML.

实际上,您的'&lt;p class="bio "&gt;''(.*?)' 之间有一个换行符,这意味着您需要使用re.DOTALL 进行匹配,以便. 包含换行符。您也可以使用'&lt;p class="bio "&gt;\s*(.*?)\s*&lt;/p&gt;',因为\s 将匹配换行符(如果存在)。这也将提供更清晰的输出。

import re

pat = re.compile(r'<p class="bio ">\s*(.*?)\s*</p>')
pat.findall(src) # src is your last codeblock from above
## OUTPUT:
['This account is run by Organizing for Action staff. Tweets from the President are signed -bo.']

如果你想使用 BeautifulSoup 选项,Python3 代码如下:

from bs4 import BeautifulSoup

soup = BeautifulSoup(src) # src is your last codeblock from your question
[p_bio.contents.strip() for p_bio in soup('p' class_='bio ')]
## OUTPUT:
['This account is run by Organizing for Action staff. Tweets from the President are signed -bo.']

【讨论】:

    【解决方案2】:

    使用 Regex 解析任意 HTML 非常困难,并且只有在您100% 确定输出会是什么样子时才真正起作用。 That said, as stated in the other really sane (but not as funny answer):

    虽然要求正则表达式解析任意 HTML 确实就像要求 Paris Hilton 编写操作系统一样,但有时解析有限的已知 HTML 集是合适的。

    如果您想要从一小部分 HTML 页面中抓取数据,然后将其填充到数据库中,那么 regexe 可能会正常工作。例如,我最近想获得澳大利亚联邦代表的姓名、政党和地区,这是我从议会网站上下载的。这是一项有限的一次性工作。

    正则表达式对我来说工作得很好,而且设置起来非常快。

    这意味着检查源代码,而不是浏览器开发工具中的 DOM。

    对于您当前的示例,如前面的示例所述,您没有捕获换行符,因此您需要添加 appropriate regex flags

    splitSource = re.findall(r'<p class="bio ">(.*?)</p>', pageSource, flags=re.DOTALL)
    

    更好的解决方案包括使用 HTML 特定工具,例如 BeautifulSoup,因为它们可以处理 HTML 特性。例如,您正在对无序的类名进行正则表达式匹配。

    所以这些是相同的 html 声明:

    <div class="foo bar">
    <div class="bar foo">
    

    但是正则表达式引擎和 XML 解析器在使用相同的查询时都会遇到问题,而 HTML 特定工具可以使用 CSS 选择器来查找它们。

    【讨论】:

    • 我认为这里不需要re.MULTILINE
    • 否则正则表达式不会换行到下一行,这意味着正则表达式会在行尾停止并且永远找不到文本或所需的结束标记。
    • re.MULTILINE 仅影响 ^$ 标记 per the docsre.DOTALL 允许 . 字符匹配换行符。
    • 实际上,我的立场是正确的。我会删除它。谢谢:)
    • 不用担心,我不记得它是否也需要它,然后去挖掘文档:)。也就是说,我仍然认为我的代码更干净,因为您的代码将返回前导和空格,而不仅仅是文本:)
    猜你喜欢
    • 2018-05-11
    • 2018-12-28
    • 1970-01-01
    • 2019-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-14
    • 1970-01-01
    相关资源
    最近更新 更多