两页有相同的网址。如何爬行?

时间:2013-07-18 18:01:15

标签: web-crawler scrapy

我将展示我的确切示例,但我认为对于一般情况,您必须抓取一个网址,其网址会将您引导至其他网页,这可能会出现问题。

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

如何让蜘蛛以我想要的方式开始?

由于

1 个答案:

答案 0 :(得分:2)

“show all”链接是对网页上的Javascript函数的调用,它的调用方式如下:

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

我的主要浏览器是Firefox,它具有您可以使用的出色附加组件。 我使用了“Web Developer”插件。

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

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

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

如果if-statemment中的测试计算结果为true,那么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-tag的引用,它具有id属性'aspnetForm'(id ='aspnetForm'),这意味着在HTML文档中我们shold寻找像这样开始的东西:

<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请求中使用的变量和值。

要做到这一点,我在JavaScript打开时再次使用Firefox。 此外,我正在使用令人敬畏的Firebug Add-On。 在第一个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个输入标签的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”对input-tag的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解析器放在工作上。