如何在响应为 html/文本而不是 json 的情况下抓取具有无限滚动的网页。
我的第一次尝试是使用 Rule 和 LinkExtractor,这让我获得了大约 80% 的工作 url
class JobsetSpider(CrawlSpider):
name = 'test'
allowed_domains = ['jobs.et']
start_urls = ['https://jobs.et/jobs/']
rules = (
Rule(LinkExtractor(allow='https://jobs.et/job/\d+/'), callback='parse_link'),
Rule(LinkExtractor(), follow=True),
)
def parse_link(self, response):
yield {
'url': response.url
}
我的第二次尝试是使用 SCRAPING INFINITE SCROLLING PAGES 中的示例但响应是文本/html 而不是 json。
当点击“加载更多”按钮时,我可以从 Chrome 开发者工具上的网络中看到请求 url
https://jobs.et/jobs/?searchId=1509738711.5142&action=search&page=2
同时“页”数增加。
我的问题是
- 如何使用 scrapy 从响应 header 中提取上述 url 单击“加载更多”按钮
- 有没有更好的方法来解决这个问题?
最佳答案
忽略“加载更多”按钮。
如您所述,您可以使用 URL 访问所有职位页面。当您解析第一页结果时,从标题元素中找到职位总数
<h1 class="search-results__title ">
268 jobs found
</h1>
网站每页显示 20 个职位,因此您需要抓取 268/20 = 13.4(四舍五入为 14)页。
当您完成第一个页面的解析后,创建一个生成器为后续页面生成 URL(循环最多 14 个)并使用另一个函数解析结果。您将需要 searchId
,您无法从 URL 中获取它,但它位于页面的隐藏字段中。
<input type="hidden" name="searchId" value="1509738711.5142">
使用它和页码你可以构建你的 URL
https://jobs.et/jobs/?searchId=<id>&action=search&page=<page>
是的,解析函数将与您的第一个页面解析器完全相同,但是当您使它全部正常工作时,最好忍受代码重复以保持头脑清晰。
这个代码可能是这样的
class JobsetSpider(CrawlSpider):
...
start_urls = ['https://jobs.et/jobs/']
...
def parse(self, response):
# parse the page of jobs
...
job_count = xpath(...)
search_id = xpath(...)
pages = math.ceil(job_count / 20.0)
for page in range(2, pages):
url = 'https://jobs.et/jobs/?searchId={}&action=search&page={}'.format(search_id, page)
yield Request(url, callback = self.parseNextPage)
def parseNextPage(self, response):
# parse the next and subsequent pages of jobs
...
关于python - 使用 Scrapy 抓取带有 "load more"按钮的无限滚动页面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47104156/