【问题标题】:Scrapy/Python XMLHTTPRequestScrapy/Python XMLHTTPRequest
【发布时间】:2020-05-28 03:35:06
【问题描述】:

我构建了一个可以工作到一定程度的刮板:它导航到记录列表,将记录解析为关键记录以进行进一步抓取,转到这些单独的记录,但无法解析记录中的表,因为它们已加载通过 JavaScript。 JavaScript 发出一个POST 请求(xmr)来填充它们。因此,如果未启用 JavaScript,它会返回类似“未找到记录”之类的信息。

所以我读到了这个问题:Link

我使用浏览器开发工具检查了请求标头。标头包括:

fetch("https://example.com/Search/GridQuery?query=foo", {
  "headers": {
    "accept": "text/plain, */*; q=0.01",
    "accept-language": "en-US,en;q=0.9,es;q=0.8",
    "cache-control": "no-cache",
    "content-type": "application/x-www-form-urlencoded",
    "pragma": "no-cache",
    "sec-fetch-dest": "empty",
    "sec-fetch-mode": "cors",
    "sec-fetch-site": "same-origin",
    "x-requested-with": "XMLHttpRequest"
  },
  "referrer": "https://example.com/SiteSearch/Search?query=bar",
  "referrerPolicy": "no-referrer-when-downgrade",
  "body": "page=1&size=10&useFilters=false",
  "method": "POST",
  "mode": "cors",
  "credentials": "include"
});

浏览器确实指示了一个cookie,虽然不是通过复制获取输出... 然后我尝试了这个:

url = response.urljoin(response.css('div#Foo a::attr(href)').get())
yield Request(url=url,
              method='POST',
              body='{"filters": ["page": "1", "size": "10", "useFilters": "False"]}',
              headers={'x-requested-with': 'XMLHttpRequest'},
              callback=self.parse_table)

我收到回复,但仍然显示“未找到记录”。所以POST 请求不能正常工作。

我需要将所有内容都放在请求标头中吗?如何确定必须包含哪些内容?是否需要 Cookie?

【问题讨论】:

    标签: python scrapy xmlhttprequest


    【解决方案1】:

    我没有对此进行测试,因为您没有提供真实的网址,但我发现那里存在一些问题。
    请注意,内容类型是application/x-www-form-urlencoded,并且您在正文中发送 JSON 对象(用于application/json

    相反,您应该发送FormRequest:

    url = "https://example.com/Search/GridQuery?query=foo"
    form_data = {"page": "1", "size": "10", "useFilters": "False"}
    yield FormRequest(url, formdata=form_data, callback=self.parse_table)
    

    或者只是在URL中添加参数作为查询参数(仍然是POST请求,只是省略正文)。

    url="https://example.com/Search/GridQuery?query=foo&page=1&size=10&useFilters=False"
    

    无论哪种方式,您都不需要"filters":[],只需使用简单的键值对象即可。

    【讨论】:

    • 我修改了 header 以等于 fetch 返回的所有内容。然后我将 body 设置为 fetch 返回的字符串。 yield Request(url=url, method='POST', body="page=1&size=10&useAnyMatchWithFilters=false", headers=headers, callback=self.parse_table) 现在它返回一个文本文件(请求是针对“text/plain”的,大概是一个 JSON 对象。我怀疑这是由 HTML 中的脚本对象解析来制作表格的。需要弄清楚如何带有 JSON 的 scrapy .txt。
    • 我不确定我理解你的意思,但如果你得到一个有效的 JSON 对象,你可以使用json.loads(response.body_as_unicode()) 加载它。如果文本包含' 而不是",它可能会失败,所以在这种情况下输入json.loads(response.body_as_unicode().replace("'", '"'))
    • 哇。你为我节省了几天的研究时间。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2018-12-13
    • 1970-01-01
    • 2017-04-17
    • 2013-03-05
    • 2013-04-07
    • 2013-08-08
    • 2020-05-31
    • 2017-06-07
    相关资源
    最近更新 更多