我目前正在开发一个网络抓取项目,使用 Scrapy 从 https://www.discoveruni.gov.uk/course-finder/results/ 提取课程信息。由于网站的动态加载行为,我遇到了挑战,这与我以前的抓取经验不同。
最初,我成功地从第一页检索到信息。然而,在检查网站时,我注意到 XHR 响应不包含预期的 JSON 数据;他们是空的。
这是我当前的 Scrapy 蜘蛛的片段:
class UnispiderSpider(scrapy.Spider):
name = 'unispider'
# allowed_domains = ['www.discoveruni.gov.uk']
start_urls = ['https://www.discoveruni.gov.uk/course-finder/results/']
base_url = 'https://www.discoveruni.gov.uk/course-finder/results/'
def parse(self, response):
course_list = response.xpath(
'//div[@class="course-finder-results__result-accordion-body-content comparison-course-area mb-4"]')
for course in course_list:
courseidentifier = course.xpath('@data-courseidentifier').get()
uniname = course.xpath('@data-uniname').get()
uniid = course.xpath('@data-uniid').get()
coursename = course.xpath('@data-coursename').get()
link = course.xpath('a/@href').get()
yield {
'courseidentifier': courseidentifier,
'uniname': uniname,
'uniid': uniid,
'coursename': coursename,
'link': link
}
我主要关心的是弄清楚如何导航到下一页并继续抓取。由于 XHR 响应不提供预期的 JSON 数据,因此我不确定处理分页的正确方法。
任何有关如何解决此问题的见解或指导将不胜感激。
谢谢!!!
我使用 scrapy 成功检索了第一页的信息,但我知道如何转到下一页。
在观察网络活动时,尝试按
All
选项卡而不是 XHR
以查看对下一页内容发出的发布请求。这是实现这一目标的方法之一。
class UnispiderSpider(scrapy.Spider):
name = 'unispider'
# allowed_domains = ['www.discoveruni.gov.uk']
start_urls = ['https://www.discoveruni.gov.uk/course-finder/results/']
base_url = 'https://www.discoveruni.gov.uk/course-finder/results/'
payload = {
'count': '20',
'sort_by_subject': 'false',
'course_query': '',
'location_radio': 'region',
}
def parse(self, response):
if not response.css('.comparison-course-area'):
return
for course in response.css('.comparison-course-area'):
yield {
'courseidentifier': course.xpath('@data-courseidentifier').get(),
'uniname': course.xpath('@data-uniname').get(),
'uniid': course.xpath('@data-uniid').get(),
'coursename': course.xpath('@data-coursename').get(),
'link': course.xpath('a/@href').get()
}
next_page_num = response.meta.get("page",1) + 1
self.payload['csrfmiddlewaretoken'] = response.css('[name="csrfmiddlewaretoken"]::attr(value)').get()
self.payload['page'] = str(next_page_num)
yield scrapy.FormRequest(
self.base_url,
method='POST',
formdata=self.payload,
callback=self.parse,
meta={"page": next_page_num}
)