Python 使用Scrapy和Splash遍历AJAX页面上的选择项

Python 使用Scrapy和Splash遍历AJAX页面上的选择项,python,web-scraping,scrapy,scrapy-spider,scrapy-splash,Python,Web Scraping,Scrapy,Scrapy Spider,Scrapy Splash,我正在刮一页,用刮擦和飞溅。该页面包含一个下拉框(从技术上讲,是一个selecthtml元素)。每次在下拉框中选择一个元素时,都会使用AJAX加载一个新页面 下面的HTML段是我正在处理的页面的简化版本: <html> <head><title>Title goes here ...</title></head> <body> <select class="foo">

我正在刮一页,用刮擦和飞溅。该页面包含一个下拉框(从技术上讲,是一个selecthtml元素)。每次在下拉框中选择一个元素时,都会使用AJAX加载一个新页面

下面的HTML段是我正在处理的页面的简化版本:

<html>
    <head><title>Title goes here ...</title></head>
    <body>
        <select class="foo">
            <option value=100 data-reactid=1>One</option>
            <option value=200 data-reactid=2>Two</option>
            <!-- ... -->
            <option value=900 data-reactid=9>Nine</option>
        </select>
    </body>
</html>

如何以编程方式使用Splash“单击”并在我的响应对象中接收重新加载的AJAX页面?

您可以尝试使用带有LUA脚本的Splash的
执行
端点,该脚本将用每个
选项
的值填充
选择
,并返回结果。比如:

...
script = """
function main(splash)
    splash.resource_timeout = 10
    splash:go(splash.args.url)
    splash:wait(1)
    splash:runjs('document.getElementsByClassName("foo")[0].value = "' .. splash.args.value .. '"')
    splash:wait(1)
    return {
        html = splash:html(),
    }
end
"""

# base_url refers to page with the select
values = response.xpath('//select[@class="foo"]/option/@value').extract()
for value in values:
    yield scrapy_splash.SplashRequest(
        base_url, self.parse_result, endpoint='execute',
        args={'lua_source': script, 'value': value, 'timeout': 3600})

当然,这没有经过测试,但您可以从那里开始使用它。

这些ajax请求的格式相同吗?为了模拟单击操作,您可以通过编程构造该格式并发送ajax请求以获得响应。@Sraw ajax意味着单击元素时浏览器中正在运行javascript。我当然知道,但它们也不过是普通的http请求。若你们使用chrome,你们可以在开发者工具的“网络”下看到这些请求。因此,您也可以模拟ajax请求,就像您
GET
POST
到网站一样。我的意思是,如果这些ajax请求具有相同的格式,您可以轻松地构建这种格式。您也可以很容易地直接模拟这些ajax请求,即使不爬网此html页面。@Sraw请参阅我以前的评论。非常感谢您的帮助-我刚刚注意到您的答案。我对它投了更高的票,因为它给了我一些开始的东西。一旦我能够从您在回答中提供的起点着手解决问题,我将接受您的回答-如果我陷入解决问题的困境,我可能会带着一个问题返回给您-希望您不介意。当然,在需要时询问。您能解释这行吗?:
splash:runjs('document.getElementsByClassName(“foo”)[0]。值=“…splash.args.value..”)
我不明白这与页面上下拉元素的“单击”有什么关系。相应的行设置了select控件的值。这可能会触发链接到此事件的AJAX代码(即更改所选选项)。谢谢。我仍在处理此问题。希望尽快解决此问题。
...
script = """
function main(splash)
    splash.resource_timeout = 10
    splash:go(splash.args.url)
    splash:wait(1)
    splash:runjs('document.getElementsByClassName("foo")[0].value = "' .. splash.args.value .. '"')
    splash:wait(1)
    return {
        html = splash:html(),
    }
end
"""

# base_url refers to page with the select
values = response.xpath('//select[@class="foo"]/option/@value').extract()
for value in values:
    yield scrapy_splash.SplashRequest(
        base_url, self.parse_result, endpoint='execute',
        args={'lua_source': script, 'value': value, 'timeout': 3600})