我试图从与此类似的很多页面中获取平均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
是零,但至少有一个h3元素包含" GPA"。
可能导致此问题的原因是什么?我认为可能是因为页面有动态元素,而Mechanize遇到了一些问题,但我可以puts page.body
并且输出包括:
... <h3 style="text-align:center;">GPA REQUIREMENT</h3> ...
根据我的理解,应该找到我使用的xpath。
如果有更好的方法,我也想知道。
答案 0 :(得分: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
的经验,但我会做类似的事情:
'(<style=\'.*)</td>'
匹配的部分,或自行关闭标记。现在您可以使用xpath选择器了。
答案 1 :(得分:1)
eLRuLL给出了上述问题的根源。以下是我如何解决问题的示例:
def camelize(string)
string.split('_').map(&:capitalize).join
end
这将返回我在上面寻找的标题:
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
答案 2 :(得分:1)
更可靠的解决方案是使用像nokogumbo这样的HTML5解析器:
require 'nokogumbo'
doc = Nokogiri::HTML5(page.body)
gpa_headers = doc.search('//h3[contains(text(), "GPA")]')