【问题标题】:Searching by text with Mechanize/Nogokiri使用 Mechanize/Nogokiri 按文本搜索
【发布时间】:2016-12-21 03:37:16
【问题描述】:

我正在尝试从许多与此类似的页面中抓取一些平均 GPA 数据和更多数据:

http://www.ptcas.org/ptcas/public/Listing.aspx?seqn=3200&navid=10737426783

require 'mechanize'

agent = Mechanize.new
page = agent.get('http://www.ptcas.org/ptcas/public/Listing.aspx?seqn=3200&navid=10737426783')
gpa_headers = page.xpath('//h3[contains(text(), "GPA")]')
pp gpa_headers

我的问题是gpa_headers 为 nil,但至少有一个 h3 元素包含“GPA”。

什么可能导致此问题?我认为可能是因为页面有动态元素,Mechanize 对此有一些问题,但我可以puts page.body 并且输出包括:

... <h3 style="text-align:center;">GPA REQUIREMENT</h3> ...

根据我的理解,应该可以在我使用的 xpath 中找到。

如果有更好的方法,我也想知道。

【问题讨论】:

    标签: ruby web-scraping nokogiri mechanize


    【解决方案1】:

    这似乎是网站的 DOM 结构的问题,因为它包含一个名为 style 的标签,它没有被关闭,看起来像这样:

    <td colspan='7'><style='text-align:center;font-style:italic'>The
    institution has been granted Candidate for Accreditation status by the
    Commission on Accreditation in Physical Therapy Education (1111 North
    Fairfax Street, Alexandria, VA, 22314; phone: 703.706.3245; email: <a
    href='mailto:accreditation@apta.org'>accreditation@apta.org</a>).
    Candidacy is not an accreditation status nor does it assure eventual
    accreditation. Candidate for Accreditation is a pre-accreditation
    status of affiliation with the Commission on Accreditation in Physical
    Therapy Education that indicates the program is progressing toward
    accreditation.</td>
    

    如您所见,td 标记关闭,但内部 style 从未关闭。

    如果您不需要这部分代码,我建议您在尝试使用整个 response 之前删除它。我没有使用ruby 的经验,但我会做类似的事情:

    • 获取响应的原始正文。
    • 将与此正则表达式'(&lt;style=\'.*)&lt;/td&gt;'匹配的部分替换为空字符串,或自行关闭标签。
    • 使用这个新的响应正文。

    现在您可以使用 xpath 选择器了。

    【讨论】:

    • 谢谢!这似乎是问题所在。
    • np,很高兴我能帮上忙。
    【解决方案2】:

    eLRuLL 给出了上述问题的根源。以下是我如何解决此问题的示例:

    require 'mechanize'
    require 'nokogiri'
    
    agent = Mechanize.new
    page = agent.get('http://www.ptcas.org/ptcas/public/Listing.aspx?seqn=3200&navid=10737426783')
    mangled_text = page.body
    fixed_text = mangled_text.sub(/<style=.+?<\/td>/, "</td>")
    page = Nokogiri::HTML(fixed_text)
    gpa_headers = page.xpath('//h3[contains(text(), "GPA")]')
    pp gpa_headers
    

    这将返回我在上面寻找的标题:

    [#<Nokogiri::XML::Element:0x2b28a8ec0c38 name="h3" attributes=[#<Nokogiri::XML::Attr:0x2b28a8ec0bc0 name="style" value="text-align:center;">] children=[#<Nokogiri::XML::Text:0x2b28a8ec0774 "GPA REQUIREMENT">]>]
    

    【讨论】:

      【解决方案3】:

      更可靠的解决方案是使用像 nokogumbo 这样的 HTML5 解析器:

      require 'nokogumbo'
      doc = Nokogiri::HTML5(page.body)
      gpa_headers = doc.search('//h3[contains(text(), "GPA")]')
      

      【讨论】:

        猜你喜欢
        • 2020-07-26
        • 2015-08-23
        • 2017-08-10
        • 2015-03-25
        • 2019-02-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-05-18
        相关资源
        最近更新 更多