使用Scrapy刮取使用XMLHttpRequests加载其内容的站点

2024-09-29 01:24:09 发布

您现在位置:Python中文网/ 问答频道 /正文

我尝试搜索的网站(在浏览器中)一次返回50个职位。当我尝试使用scrapy返回所有的职务头衔时,它只会刮去其中的20个。你知道吗

网页链接: https://recruiting.ultipro.com/COM1038/JobBoard/d22da326-8928-4fbc-8b3b-99b6db355d5d/?q=&o=postedDateDesc

当我转到这个页面时,我意识到内容是动态呈现的,所以我右键单击并检查了这个页面,然后用Dev Tools中打开的XHR>;Network选项卡重新加载它。它显示了两个文件

  1. 获取筛选器
  2. 装载机会

“LoadOpportunities”似乎很有希望,所以我查看了XHR选项卡下的“Response”,它返回了一个JSON文件,其中包含了我想要的所有信息。我使用CTRL-f搜索“Title”,找到了50个匹配项。很 完美!你知道吗

那就来测试一下。我打开Scrapy Shell,查看返回JSON的页面:

https://recruiting.ultipro.com/COM1038/JobBoard/d22da326-8928-4fbc-8b3b-99b6db355d5d/JobBoardView/LoadOpportunities

在浏览器中打开此页时,它只返回(当前)54个职位空缺中的20个。当我使用json包和scrapy shell来刮取页面时,我第一次发现了这个问题。你知道吗

当您使用我在“LoadOpportunities”文件下发布的第一个链接查看浏览器中的“Preview”选项卡时,可以看到它在“opportunities”键下最多有50个值。我正试着从每一个中提取“Title”的值。你知道吗

我还创建了一个scraper,它使用HTML响应做同样的事情,但不是特别有用。它没有完成任务,因为它实际上没有与动态网页交互,只是与初始页面连接的部分JSON文件交互。你知道吗

import scrapy, re, json, requests
from ..items import MetroSouthItems

class MetroSouth(scrapy.Spider):
    name = "metrosouth"
    start_urls = [
    'https://recruiting.ultipro.com/COM1038/JobBoard/d22da326-8928-4fbc-8b3b-99b6db355d5d/JobBoardView/LoadOpportunities',
    ]

    def parse(self, response):
        html_res = response.body
        decoded_res = str(html_res,"utf-8")
        json_file = open("metrosouth.json", "w")
        json_file.write(decoded_res)
        with open("metrosouth.json") as json_data:
            data = json.load(json_data)
            items = MetroSouthItems()
            for i in range(len(data["opportunities"])):
                items["job_title"] = data["opportunities"][i]["Title"]
                print(i)
                yield items

我想把所有可用的工作都刮下来,然后在某个时候把它们铲到数据库中/可能每天早上重新运行spider,这样我就可以跟踪新的列表。现在我让它用新的清单覆盖一个JSON文件。你知道吗

如果有人有任何前进的提示或指导,我将不胜感激。我觉得它与Javascript有关,因为它确实说“LoadOpportunities”是由jslib发起的,但我对Javascript没有太多经验,也不知道这意味着什么。你知道吗


Tags: 文件httpscomjsondata浏览器itemsres
1条回答
网友
1楼 · 发布于 2024-09-29 01:24:09

在最初的页面中,他们使用一些额外的负载发出POST请求。我们可以这样复制它:

import scrapy, json


class MetroSouth(scrapy.Spider):
    name = "metrosouth"
    search_url = url = 'https://recruiting.ultipro.com/COM1038/JobBoard/d22da326-8928-4fbc-8b3b-99b6db355d5d/JobBoardView/LoadOpportunities'

    def start_requests(self):
        payload = """{"opportunitySearch":{"Top":100,"Skip":0,"QueryString":"","OrderBy":[{"Value":"postedDateDesc","PropertyName":"PostedDate","Ascending":false}],"Filters":[{"t":"TermsSearchFilterDto","fieldName":4,"extra":null,"values":[]},{"t":"TermsSearchFilterDto","fieldName":5,"extra":null,"values":[]},{"t":"TermsSearchFilterDto","fieldName":6,"extra":null,"values":[]}]},"matchCriteria":{"PreferredJobs":[],"Educations":[],"LicenseAndCertifications":[],"Skills":[],"hasNoLicenses":false,"SkippedSkills":[]}}"""
        yield scrapy.Request(self.search_url, method='POST', body=payload)

    def parse(self, response):
        j = json.loads(response.text)
        print '======'
        for i, row in enumerate(j.get('opportunities')):
            print i, ' - ', row.get('Title')
        print '======'

检查有效负载中的参数Top。最初它被设置为50,请求页面给我们20条记录。但我把它增加到了100张,现在我得到了全部54张唱片。 希望能有帮助。你知道吗

相关问题 更多 >