0

我将展示我的确切示例,但我认为这对于您必须抓取一个其 url 将您定向到不同页面的页面的一般情况可能是一个问题。

我要抓取的页面位于此网址http://www.oxygenboutique.com/Shoes-All.aspx下,但不是您直接点击此链接时获得的页面。我想要的是你点击“显示全部”时看到的那个。

我怎样才能让我的蜘蛛从我想要的那个开始?

谢谢

4

1 回答 1

2

“显示全部”链接是对网页上的 Javascript 函数的调用,它的调用方式如下:

__doPostBack('ctl00$ContentPlaceHolder1$PGN01','')

我的主要浏览器是 Firefox,它有很多你可以使用的插件。我使用了“Web Developer”插件。

在具有该页面的选项卡中,然后执行以下操作:让鼠标光标悬停在显示全部链接上。然后右键单击并选择“Web 开发人员”>“信息”>“查看 Javascript Alt+Shift+J” Firefox 将打开一个新选项卡,其中包含该页面正在使用的所有 Javascript。

在选项卡中 - 快速搜索找到 __doPostBack 函数,其编码如下:

function __doPostBack(eventTarget, eventArgument) {
    if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
        theForm.__EVENTTARGET.value = eventTarget;
        theForm.__EVENTARGUMENT.value = eventArgument;
        theForm.submit();
    }
}

如果 if 语句中的测试结果为真,那么 JavaScipt 函数可以简化为下面的 JavaScript 代码,并且我们使用函数调用中的参数:

theForm.__EVENTTARGET.value = 'ctl00$ContentPlaceHolder1$PGN01';
theForm.__EVENTARGUMENT.value = '';
theForm.submit();

现在我们需要知道“theForm”是什么。

下面的代码位于 __doPostBack 函数的正上方:

var theForm = document.forms['aspnetForm'];
if (!theForm) {
    theForm = document.aspnetForm;
}

我们现在知道'theForm'是对'form' HTML标签的引用,它具有id属性'aspnetForm'(id='aspnetForm'),这意味着我们要在HTML文档中寻找像这样开始的东西:

<form id="aspnetForm"

要知道该标签是如何编写的,我将使用 Firefox 浏览器查看您感兴趣的页面的修改后的 HTML。 这里我使用的是 FireBug 插件。

HTML 表单的开始标签如下所示:

<form id="aspnetForm" onsubmit="javascript:return WebForm_OnSubmit();"
 action="/Shoes-All.aspx" method="post" name="aspnetForm">

所以这个动作是使用同一个 HTML 文档!

让我们看看 WebForm_OnSubmit() 函数在做什么:

function WebForm_OnSubmit() {
    if (typeof(ValidatorOnSubmit) == "function" && ValidatorOnSubmit() == false)
        return false;
    return true;

}

让我们看一下 ValidatorOnSubmit() 函数和它使用的一个有趣的变量:

var Page_ValidationActive = false;

// ...

function ValidatorOnSubmit() {
    if (Page_ValidationActive) {
        return ValidatorCommonOnSubmit();
    }
    else {
        return true;
    }
}

这意味着该函数将始终返回“true”,因此我们现在可以将表单 start-tag 重写为:

<form id="aspnetForm" onsubmit="javascript:return true;"
 action="/Shoes-All.aspx" method="post" name="aspnetForm">

由此我们可以得出结论,需要从网络服务器重新加载网页。

现在我们需要知道在 HTTP POST 请求中使用了哪些变量和值。

为此,我再次使用 Firefox 并打开了 JavaScript。另外,我正在使用很棒的 Firebug 插件。 在第一个 div 标签的 Form-element 中,我们发现:

<div>
    <input id="__EVENTTARGET" type="hidden" 
        value="" name="__EVENTTARGET">
    <input id="__EVENTARGUMENT" type="hidden" value="" name="__EVENTARGUMENT">
    <input id="__LASTFOCUS" type="hidden" value="" name="__LASTFOCUS">
    <input id="__VIEWSTATE" type="hidden"
        value="(lots of data here)" name="__VIEWSTATE">
</div>

如果你还记得我们之前的精简 javascript 代码,它修改了表单中 2 个 input-tags 的 value 属性,所以 HTML 已经被那个函数修改了,所以它真的是:

<div>
    <input id="__EVENTTARGET" type="hidden" 
        value="ctl00$ContentPlaceHolder1$PGN01" name="__EVENTTARGET">
    <input id="__EVENTARGUMENT" type="hidden" value="" name="__EVENTARGUMENT">
    <input id="__LASTFOCUS" type="hidden" value="" name="__LASTFOCUS">
    <input id="__VIEWSTATE" type="hidden"
        value="(lots of binary data here)" name="__VIEWSTATE">
</div>

您当然需要对 id 为“_VIEWSTATE”的输入标签的 value 属性的内容进行逐字复制。

仅供参考,Firefox 说 _VIEWSTATE 输入标签 XPath 是:

 //*[@id="__VIEWSTATE"]

...并且它的 CSS 选择器是:

form#aspnetForm div input#__VIEWSTATE

从网络服务器下载所有项目后,您将需要解析 HTML 页面。

有趣的内容深深地嵌入到表单中。它是一个 HTML 表格。

该表的相关 XPath 是:

//*[@id="ctl00_ContentPlaceHolder1_dlList"]

...而CSS选择器是

table#ctl00_ContentPlaceHolder1_dlList

它包含一个 tbody、tr、td、div 和另一个表格(=更糟糕的设计 - 有人需要了解无表格设计。HTML 表格在智能手机和平板电脑上看起来很糟糕。)

我认为此时您应该使用 Beautiful Soup 4 解析器。

于 2013-07-19T07:48:40.303 回答