使用Scrapy抓取基于ASP.NET的网站(https://www.proxymonitor.org/)的内容

bogh5gae  于 2022-11-09  发布在  .NET
关注(0)|答案(1)|浏览(116)

我正在尝试从www.example.com的ASP.NET中抓取2022个结果proxymonitor.org。我已经提取了网站上的所有隐藏变量,并将它们发送到FormRequest中。但我仍然从服务器接收到空表。你知道我遗漏了什么吗?
下面是我的代码:

from requests import request
    import scrapy
    from scrapy.http import FormRequest

    class ProxyMonitorSpiderSpider(scrapy.Spider):
        name = 'proxy_monitor_spider'

        allowed_domains = ['proxymonitor.org']
        start_urls = [
            'https://www.proxymonitor.org'
        ]

        def parse(self, response):

            formdata = {
                # response.css('input#__EVENTTARGET::attr(value)').extract_first(),
                '__EVENTTARGET': '',
                '__EVENTARGUMENT': '',
                '__VIEWSTATE': response.css('input#__VIEWSTATE::attr(value)').extract_first(),
                '__VIEWSTATEGENERATOR': response.css('input#__VIEWSTATEGENERATOR::attr(value)').extract_first(),
                '__PREVIOUSPAGE': response.css('input#__EVENTVALIDATION::attr(value)').extract_first(),
                '__EVENTVALIDATION': response.css('input#__EVENTVALIDATION::attr(value)').extract_first(),
                # 'ctl00_ContentPlaceHolder1_ctrlQuickSearch1_cmbYr1': '2022',

                # 'DXScript': response.css('input#__DXScript::attr(value)').extract_first(),

                # '__CALLBACKID': 'ctl00$ContentPlaceHolder1$ctrlQuickSearch1$CountCallback',
                # '__CALLBACKPARAM': 'c0:',

                'ctl00_ContentPlaceHolder1_ctrlQuickSearch1_cmbYr1_VI': '2022',
                'ctl00_ContentPlaceHolder1_ctrlQuickSearch1_cmbYr2_VI': '2022',

                'ctl00$ContentPlaceHolder1$ctrlQuickSearch1$cmbYr1': '2022',
                'ctl00$ContentPlaceHolder1$ctrlQuickSearch1$cmbYr1$DDD$L': '2022',

                'ctl00$ContentPlaceHolder1$ctrlQuickSearch1$cmbYr2': '2022',
                'ctl00$ContentPlaceHolder1$ctrlQuickSearch1$cmbYr2$DDD$L': '2022',
            }
            # print('***form data',formdata)
            req = scrapy.FormRequest.from_response(
                response, url='https://www.proxymonitor.org/Results.aspx', formdata=formdata, callback=self.parse2)

            yield req

        def parse2(self, response):
            print('***status:', response.status)
            with open('response2.html', 'w') as html_file:
                html_file.write(response.text)

            for row in response.xpath('//*[@class="dxgvTable_Office2010Silver"]//tbody//tr[position() = 2]'):
                yield {
                    'resolution_name': row.xpath('td[2]//text()').extract_first(),
                    'agm_date': row.xpath('td[3]//text()').extract_first(),
                    'company': row.xpath('td[4]//text()').extract_first(),
                    'lead_filer': row.xpath('td[5]//text()').extract_first(),
                    'status': row.xpath('td[6]//text()').extract_first(),
                }
jvidinwx

jvidinwx1#

但是,用c#或其他语言编写的网页代码中的所有可能的变量呢?可能会有大量的服务器代码值和变量。除非你从login + start页面启动,否则很有可能你没有正确设置代码(用c#或www.example.com编写)中的一些值和设置变量vb.net。你只能使用和设置客户端的值,你没有办法设置服务器端的代码值--而且它们只存在于服务器端。这包括代码变量和session()值。viewstate是客户端,但并不总是足够的。
因此代码背后是完整的. netc #或vb.net代码。该代码背后可以有一船的变量和值,必须设置为100%正确。
如果你可以用你的浏览器跳转到那个网址,然后点击按钮等,页面就能正常工作了?那么你可能可以做到这一点。但是,如果你必须导航到当前页面之前有几个页面,那么你必须先加载那些之前的页面,点击正确的按钮,然后导航到当前页面。
在我的许多页面中,我有大量的代码隐藏在类对象后面,这就是我如何驱动后面的代码。在许多情况下,如果缺少一个值,我会跳回到上一页。
因此,我可能有一个选择项目要处理。当您选择该项目时,我将创建一个包含大约10个值的类,这些值将在下一页中使用。
因此,你不能“跳过”前面的页面。我的代码经常检查不正确的值,或缺少的值。
所以,我可能会这样:

If IsPostBack = False Then

        If Session("PKID") Is Nothing Then
            ' JUMP to Issues list
            Response.Redirect("Issues")
        End If
        If Session("PKID") = 0 Then
            Response.Redirect("Issues")
        End If

在上图中,数据库PK行ID从不暴露在客户端。因此,您永远无法提取数据,也永远无法使此页面工作,除非您在上一页,单击要编辑的行,会话()值设置好,然后跳转到下一个网页.您不能触摸、也不控制会话。上面是一个简单的例子。通常代码中有一组10+个变量,这是前2-3页导航的结果。
而且,虽然视图状态是客户端的,但它是加密的,更改这些值也会使页面和后面的代码混乱。
这使得对www.example.com应用程序进行Web抓取asp.net变得非常困难,因为在大多数情况下,您不能只点击一个页面,而是必须单击并导航到前面的页面才能获取到当前页面,这是唯一的方法来确保许多代码背后的值和代码变量被正确设置。这样的代码和值的设置是100%发生在服务器端-这样值和代码的客户端侧暴露就不会发生。
如果你能在浏览器中直接跳转到一个给定的URL,并且页面100%正确,那么你就可以实现你的目标。但是,如果你当前所在的页面需要以前的导航才能到达该页面,那么你就必须重新生成这些步骤来GET到给定的页面,然后自动化,在控件中输入值,点击按钮,这些都可以而且应该起作用。
所以,不,你还没有提取所有的隐藏变量,因为变量和对象背后的代码永远不会暴露在客户端,并且在你点击任何按钮或尝试在该网页上进行任何其他操作之前,点击一个按钮通常会在代码背后设置变量和值。
如果不是因为.net框架和完整的.net编码系统在后面运行来驱动这个网页,那么这将是微不足道的。但是,编写漂亮的.net代码的能力和容易性也使得抓取一些asp.net页面非常困难,因为你试图与服务器端的.net代码交互,而你没有使用这些代码,也不能更改后面的代码例程中使用的值。
请记住上述页面的“上一个导航”。
因此,如果你可以跳转并点击该网页(在浏览器中),它的工作,那么你仍然有一个很好的机会在这里,但你不能跳过任何步骤,一个普通用户会采取的,以获得该页面,并在他们点击一个按钮或一些这样的页面返回数据的点。

相关问题