python - 抓取互动网站

标签 python scrapy

我正在尝试删除类(class)名称,其中学生人数来自 Udacity找出哪些类(class)最受欢迎。我设法为项目创建代码:

import scrapy
class UdacityItem(scrapy.Item):
    name=scrapy.Field()
    users=scrapy.Field()

和蜘蛛:

import scrapy
from Udacity.items import UdacityItem
import re

class DmozSpider(scrapy.Spider):
    name = "UdSpider"
    allowed_domains = ["udacity.com"]
    start_urls = ["https://www.udacity.com/courses/all"]

    def parse(self, response):

        sites = response.xpath('//h3/a')
        for s in sites:
            t=UdacityItem()
            #name & url
            t['name']=s.xpath('text()').extract()[0].strip()
            url=response.urljoin(s.xpath('@href').extract()[0])
            #request
            req=scrapy.Request(url, callback=self.second)
            req.meta['item']=t
            #execute
            yield req 

    def second(self,response):
        t=response.meta['item']
        strong =response.xpath('//strong[@data-course-student-count]/text()').extract()[0]
        t['users']=strong
        yield t

结果,我得到了类(class)的名称,但我得到的不是学生数量,而是文本“数千”。当我打开 example website在浏览器中,我看到“数千”是基值,稍后(1-2秒内)此文本将更改为正确的数字(我想要获得)。

这是我的问题:

  1. 为什么会发生这种替换?这是 JavaScript 代码吗?我会 喜欢了解这种变化的机制。
  2. 如何使用 scrapy 捕获适当数量的学生?我希望这是可能的。

提前感谢您提供的帮助。

最佳答案

要获取注册人数,您必须模拟针对特定类(class) ID 的 https://www.udacity.com/api/summaries 端点的 API 请求,该 ID 可以从URL 本身 - 例如,https://www.udacity.com/course/javascript-promises--ud898 URL 为 ud898

完整的蜘蛛:

import json

import re
from urllib import quote_plus

import scrapy


class UdacityItem(scrapy.Item):
    name = scrapy.Field()
    users = scrapy.Field()


class DmozSpider(scrapy.Spider):
    name = "UdSpider"
    allowed_domains = ["udacity.com"]
    start_urls = ["https://www.udacity.com/courses/all"]

    def parse(self, response):
        sites = response.xpath('//h3/a')
        for s in sites:
            t = UdacityItem()
            # name & url
            t['name'] = s.xpath('text()').extract()[0].strip()
            url = response.urljoin(s.xpath('@href').extract()[0])
            # request
            req = scrapy.Request(url, callback=self.second)
            req.meta['item'] = t
            # execute
            yield req

    def second(self, response):
        queries = [{
            "limit": 1,
            "model": "CourseStudentsSummary",
            "locator": {
                "sample_frequency": "daily",
                "content_context": [{
                    "node_key": re.search(r'--(.*?)$', response.url).group(1)
                }]
            }
        }]
        yield scrapy.Request(method="GET",
                             url="https://www.udacity.com/api/summaries?queries=" + quote_plus(json.dumps(queries)),
                             callback=self.parse_totals)

    def parse_totals(self, response):
        print(json.loads(response.body[5:].strip())["summaries"]["default"][0]["data"]["total_enrollments"])

关于python - 抓取互动网站,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36438539/

相关文章:

python - 针对 Windows 计算机使用 impacket 的 SMB 客户端时“无法请求 session ”

python - ftplib MLSD 命令给出 500 Unknown command

python - 如何重启Scrapy spider

python - 如何从回调返回空结果并继续抓取?

python - 使用scrapy获取javascript回发参数

python - 如何在Python中使用当前的Python解释器运行外部Python脚本?

python - 这是子类化 python 线程以接受变量更新的有效方法吗?

python - 向 opencv python 添加额外的模块?

python - 使用scrapy分页

python - Scrapy如何在爬取完所有页面后运行函数