gpt4 book ai didi

python - 提交使用 Scrapy 动态呈现的表单?

转载 作者:太空宇宙 更新时间:2023-11-04 10:26:12 26 4
gpt4 key购买 nike

我正在尝试使用 Scrapy 提交一个动态生成的用户登录表单,然后在对应于成功登录的页面上解析 HTML。

我想知道如何使用 Scrapy 或 Scrapy 和 Selenium 的组合来做到这一点。 Selenium 可以在 DOM 上找到元素,但我想知道在获得完整的 HTML 后是否可以将控制权“交还给”Scrapy,以允许它执行表单提交并保存必要的 cookie 、 session 数据等,以便抓取页面。

基本上,我认为需要 Selenium 的唯一原因是因为我需要在 Scrapy 查找 <form> 之前从 Javascript 渲染页面。元素。但是,还有其他替代方法吗?

谢谢!

编辑:这个问题类似于 this one ,但不幸的是,接受的答案涉及 Requests 库而不是 Selenium 或 Scrapy。尽管在某些情况下可能会发生这种情况(watch this to learn more),但正如 alecxe 指出的那样,如果“页面的某些部分 [例如表单] 通过 API 调用加载并在 javascript 的帮助下插入到页面中,则可能需要 Selenium在浏览器中执行的代码”。

最佳答案

Scrapy 实际上并不适合 coursera 网站,因为它非常异步。页面的部分内容通过 API 调用加载,并借助在浏览器中执行的 JavaScript 代码插入到页面中。 Scrapy 不是浏览器,无法处理它。

这就提出了问题 - 为什么不使用公开可用的 Coursera API

除了记录的内容之外,您还可以看到在浏览器开发人员工具中调用的其他端点 - 您需要经过身份验证才能使用它们。例如,如果您已登录,您可以看到您已修读的类(class)列表:

enter image description here

有一个对 memberships.v1 端点的调用。

举个例子,让我们启动selenium,登录并使用get_cookies() 抓取cookies .然后,让我们向 memberships.v1 端点生成一个 Request 以获取提供我们从 selenium 获得的 cookie 的存档类(class)列表:

import json

import scrapy
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


LOGIN = 'email'
PASSWORD = 'password'

class CourseraSpider(scrapy.Spider):
name = "courseraSpider"
allowed_domains = ["coursera.org"]

def start_requests(self):
self.driver = webdriver.Chrome()
self.driver.maximize_window()
self.driver.get('https://www.coursera.org/login')

form = WebDriverWait(self.driver, 10).until(EC.presence_of_element_located((By.XPATH, "//div[@data-js='login-body']//div[@data-js='facebook-button-divider']/following-sibling::form")))
email = WebDriverWait(form, 10).until(EC.visibility_of_element_located((By.ID, 'user-modal-email')))
email.send_keys(LOGIN)

password = form.find_element_by_name('password')
password.send_keys(PASSWORD)

login = form.find_element_by_xpath('//button[. = "Log In"]')
login.click()

WebDriverWait(self.driver, 20).until(EC.visibility_of_element_located((By.XPATH, "//h2[. = 'My Courses']")))

self.driver.get('https://www.coursera.org/')
cookies = self.driver.get_cookies()

self.driver.close()

courses_url = 'https://www.coursera.org/api/memberships.v1'
params = {
'fields': 'courseId,enrolledTimestamp,grade,id,lastAccessedTimestamp,role,v1SessionId,vc,vcMembershipId,courses.v1(display,partnerIds,photoUrl,specializations,startDate,v1Details),partners.v1(homeLink,name),v1Details.v1(sessionIds),v1Sessions.v1(active,dbEndDate,durationString,hasSigTrack,startDay,startMonth,startYear),specializations.v1(logo,name,partnerIds,shortName)&includes=courseId,vcMembershipId,courses.v1(partnerIds,specializations,v1Details),v1Details.v1(sessionIds),specializations.v1(partnerIds)',
'q': 'me',
'showHidden': 'false',
'filter': 'archived'
}

params = '&'.join(key + '=' + value for key, value in params.iteritems())
yield scrapy.Request(courses_url + '?' + params, cookies=cookies)

def parse(self, response):
data = json.loads(response.body)

for course in data['linked']['courses.v1']:
print course['name']

对我来说,它打印:

Algorithms, Part I
Computing for Data Analysis
Pattern-Oriented Software Architectures for Concurrent and Networked Software
Computer Networks

这证明我们可以将 selenium 中的 cookie 提供给 Scrapy,并成功地从“仅供登录用户”页面中提取数据。


此外,请确保您没有违反 Terms of Use 中的规则,具体来说:

In addition, as a condition of accessing the Sites, you agree not to ... (c) use any high-volume, automated or electronic means to access the Sites (including without limitation, robots, spiders, scripts or web-scraping tools);

关于python - 提交使用 Scrapy 动态呈现的表单?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29179519/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com