【问题标题】:Screen scrape HTML head content?屏幕抓取 HTML 头部内容?
【发布时间】:2012-04-05 13:04:38
【问题描述】:

我很乐意使用 CSS 元素作为识别我想要的内容部分的方法来抓取 HTML 内容,但我需要抓取网页部分的内容:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!-- saved from url=(0028)http://www.peoplesafe.co.uk/ -->
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title>PeopleSafe</title>
    <link href="css/screen.css" media="screen" rel="stylesheet" type="text/css" />
    <!--[if lte IE 6]>
    <link href="http://www.peoplesafe.co.uk/styles/default/screen_ie6.css" media="screen" rel="stylesheet" type="text/css" />
    <![endif]-->
    <link rel="icon" href="http://www.peoplesafe.co.uk/styles/default/favicon.ico" />

        <script type="text/javascript" src="js/tabpane.js"></script> 
    <link type="text/css" rel="StyleSheet" href="css/tab.webfx.css?v=2" />


    <meta http-equiv="Author" content="Rare Creative Group" />
    <meta http-equiv="Description" content="Experts in lone worker safety" />
    <meta http-equiv="Keywords" content="lone, worker, safety" />
    <script type="text/javascript" src="js/spotlight.js"></script>
    <script type="text/javascript" src="js/promo.js"></script>    

<script src="http://maps.google.com/maps?ile=api&amp;v=2&amp;sensor=true&amp;key=ABQIAAAA04SCF3o4CZghg6c0Qqgd-RQxzn3bXKr_TQ6C8c2CiIf8-vjJhBS3endtVbbJ1vftXL4Wbb2PwuJ8ag" type="text/javascript"></script> 
<script type="text/javascript"> 
//<![CDATA[
function load()
{
    // required for original Peoplesafe layout:
    start();

    if ( GBrowserIsCompatible() )
    {
        // codice setcenter:
        var map = new GMap2( document.getElementById( "map" ) );

        var customUI = map.getDefaultUI();
        // Remove MapType.G_HYBRID_MAP
        //customUI.maptypes.hybrid = false;
        map.setUI(customUI);
        //map.addControl( new GSmallMapControl() );
        //map.addControl( new GMapTypeControl() );

        map.setCenter( new GLatLng( 51.612308, -1.239453 ), 11 );

        // Crea un nuovo marker nel punto specificato con una descrizione HTML associata:
        function createMarker( point, description, primary_contact_id )
        {
            //var icon = new GIcon();
            ////icon.shadow = "/images/nuvola.png";
            //icon.iconSize = new GSize(87, 38);
            ////icon.shadowSize = new GSize(107, 38);
            //icon.iconAnchor = new GPoint(6, 20);
            //icon.infoWindowAnchor = new GPoint(5, 1);
            //icon.image = "/img/.";

我需要以某种方式解析这一行的纬度和经度:

map.setCenter( new GLatLng( 51.612308, -1.239453 ), 11 );

所以在我的表格的一列中,我想要第一部分:

51.612308

在第二列中,我想要第二部分:

-1.239453

如果没有 CSS 选择器,这可能吗?

编辑

感谢到目前为止的帮助,非常感谢!

最初的问题是在您登录网站后立即进行重定向,我已经对其进行了排序,现在当我这样做时:

put page.root

我得到了我期望的页面的完整来源。所以现在我的代码(登录后)是:

html_doc = page.root

# Find the first <script> in the head that does not have src="..."
#script = html.at_xpath('/html/head/script[not(@src)]')

# Use a regex to find the correct code parts in the JS, using named captures
parts = script.text.match(/new GLatLng\(\s*(?<lat>.+?)\s*,\s*(?<long>.+?)\s*\)/)

p parts[:lat], parts[:long]
#=> "51.612308"
#=> "-1.239453"

运行上述程序时出现错误:

undefined local variable or method `script' for main:Object

【问题讨论】:

  • 你不能只用 HTML 把它们放进去吗?它们是静态的吗?
  • 这是一个没有 API 的服务提供商网站,我们有权抓取但我们不能更改 HTML 代码。它们是我们为单身工人使用的电话的经纬度,因此几乎是实时的。
  • 在您的托管环境中,使用一些服务器端技术 asp.net、php、jsp 编写一个 web 方法来抓取网页数据,然后从返回的 html 内容中提取数据
  • 我有一个 rake 任务 (Ruby),它打开网页、登录并最终提取数据 - 我不知道如何提取我需要的确切数据。我在使用 CSS 选择器之前已经完成了。
  • 您的新错误是因为您从未创建过script 变量!请参阅我重新编辑的答案。 (以后,我敦促您不要盲目复制/粘贴给您的代码,而是要了解它的作用和应用方式。)

标签: ruby screen-scraping nokogiri mechanize


【解决方案1】:

这是一种解决方案;请注意,返回的部分是字符串,因此您可能需要对它们调用 to_f 来执行计算:

require 'nokogiri'
html_doc = Nokogiri.HTML(my_html)

# Find the first <script> in the head that does not have src="..."
script = html_doc.at_xpath('/html/head/script[not(@src)]')

# Use a regex to find the correct code parts in the JS, using named captures
parts = script.text.match(/new GLatLng\(\s*(?<lat>.+?)\s*,\s*(?<long>.+?)\s*\)/)

p parts[:lat], parts[:long]
#=> "51.612308"
#=> "-1.239453"

如果您不习惯使用 XPath 表达式来查找脚本,您也可以执行以下操作:

script = html.css('head script').find{ |el| el['src'].nil? }

即查找头部中的所有脚本标签,然后使用standard Ruby method 查找匹配特定条件的第一个元素。

编辑:如果您使用的是 Mechanize,它会在内部使用 Nokogiri 来解析和处理文档。您可以通过代码直接获取 Nokogiri HTML Document 对象

html_doc = my_mechanize_page.root

…或者您可以使用Mechanize::Page#at 方法在页面内容内部调用Nokogiri 自己的at

我个人更喜欢前者,因为 Nokogiri 文档为您提供了比at 更丰富的方法。但是,两者都可以使用上述代码。

编辑 2:例如:

script = page.at('/html/head/script[not(@src)]')
parts = script.text.match(/new GLatLng\(\s*(?<lat>.+?)\s*,\s*(?<long>.+?)\s*\)/)

【讨论】:

  • 使用你的第一个例子我得到一个错误。整个脚本看起来像这样gist.github.com/2312571我错过了什么吗?
  • @dannymcc 是的,你错过了一些东西。阅读错误消息的内容。然后批判性地查看脚本的第 24 行。
  • 'html = Nokogiri.HTML(my_html)' 第 24 行让我很困惑,我应该用什么替换 my_html 吗?
  • 对不起,我以为我提到了机械化!我的错。 gist.github.com/2312571 '未定义的方法文本'失败了我对 script = page.at(..) 部分有点困惑。
  • @dannymcc 请使用更新的代码和您收到的确切错误消息编辑您的问题。我认为script 无法获取脚本,但我无法确定您提供的稀疏细节。
【解决方案2】:

是的,这在没有 CSS 选择器的情况下是可能的。如果您可以将页面读入缓冲区或数组,则可以挑选出您需要的部分。

() 处分隔将允许​​您检查唯一字符串new GLatLng。您知道这将是您的纬度/经度之前的元素。另请参阅 NitinJS 的评论和此页面以获取帮助将字符串分开 http://www.tizag.com/javascriptT/javascript-string-split.php

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-20
    • 1970-01-01
    • 2011-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多