当前位置: 首页 > 面试题库 >

将InitSpider与Splash结合使用:仅解析登录页面?

云光明
2023-03-14
问题内容

我正在尝试抓取必须先登录才能访问的网页。但是在身份验证之后,我需要的网页需要运行一些Javascript才能查看内容。我已经按照此处的说明安装了启动程序,以尝试呈现Javascript。然而…

在我切换启动之前,使用Scrapy进行身份验证InitSpider是可以的。我正在浏览登录页面,然后抓取目标页面正常(显然,除非Javascript无法正常工作)。但是,一旦添加代码以通过启动请求传递请求,就好像我没有解析目标页面。

下面的spider。初始版本(此处)和非初始版本之间的唯一区别是function def start_requests()。两者之间的其他一切都相同。

import scrapy
from scrapy.spiders.init import InitSpider
from scrapy.spiders import Rule
from scrapy.linkextractors import LinkExtractor

class BboSpider(InitSpider):
    name = "bbo"
    allowed_domains = ["bridgebase.com"]
    start_urls = [
            "http://www.bridgebase.com/myhands/index.php"
            ]
    login_page = "http://www.bridgebase.com/myhands/myhands_login.php?t=%2Fmyhands%2Findex.php%3F" 

    # authentication
    def init_request(self):
        return scrapy.http.Request(url=self.login_page, callback=self.login)

    def login(self, response):
        return scrapy.http.FormRequest.from_response(
            response,
            formdata={'username': 'USERNAME', 'password': 'PASSWORD'},
            callback=self.check_login_response)

    def check_login_response(self, response):
        if "recent tournaments" in response.body:
            self.log("Login successful")
            return self.initialized()
        else:
            self.log("Login failed")
            print(response.body)

    # pipe the requests through splash so the JS renders 
    def start_requests(self):
        for url in self.start_urls:
            yield scrapy.Request(url, self.parse, meta={
                'splash': {
                    'endpoint': 'render.html',
                    'args': {'wait': 0.5}
                }
            }) 

    # what to do when a link is encountered
    rules = (
            Rule(LinkExtractor(), callback='parse_item'),
            )

    # do nothing on new link for now
    def parse_item(self, response):
        pass

    def parse(self, response):
        filename = 'test.html' 
        with open(filename, 'wb') as f:
            f.write(response.body)

现在发生的是test.html的结果parse()现在只是登录页面本身,而不是登录后应该重定向到的页面。

这是在日志中说明的-通常,我会从中看到“登录成功”行check_login_response(),但是正如你在下面看到的那样,看来我什至没有走到那一步。这是因为scrapy现在也使身份验证请求也通过启动,并且已经挂在那里了吗?如果是这样,是否有任何方法可以仅针对身份验证部分绕过启动?

2019-01-24 14:54:56 [scrapy] INFO: Spider opened
2019-01-24 14:54:56 [scrapy] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min)
2019-01-24 14:54:56 [scrapy] DEBUG: Telnet console listening on 127.0.0.1:6023
2019-01-24 14:55:02 [scrapy] DEBUG: Crawled (200) <POST http://localhost:8050/render.html> (referer: None)
2019-01-24 14:55:02 [scrapy] INFO: Closing spider (finished)

谁能指出我的一些文档以了解发生了什么情况?


问题答案:

我认为,仅Splash不能很好地处理此特殊情况。

这是工作思路:

  • 使用seleniumPhantomJS无头的浏览器登录到网站
  • 将浏览器cookie从传递PhantomJSScrapy

代码:

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


class BboSpider(scrapy.Spider):
    name = "bbo"
    allowed_domains = ["bridgebase.com"]
    login_page = "http://www.bridgebase.com/myhands/myhands_login.php?t=%2Fmyhands%2Findex.php%3F"

    def start_requests(self):
        driver = webdriver.PhantomJS()
        driver.get(self.login_page)

        driver.find_element_by_id("username").send_keys("user")
        driver.find_element_by_id("password").send_keys("password")

        driver.find_element_by_name("submit").click()

        driver.save_screenshot("test.png")
        WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.LINK_TEXT, "Click here for results of recent tournaments")))

        cookies = driver.get_cookies()
        driver.close()

        yield scrapy.Request("http://www.bridgebase.com/myhands/index.php", cookies=cookies)

    def parse(self, response):
        if "recent tournaments" in response.body:
            self.log("Login successful")
        else:
            self.log("Login failed")
        print(response.body)

打印Login successful和“手”页面的HTML。



 类似资料:
  • 问题内容: 在哪种情况下,应该只在实际部署中将Node.js用作服务器? 当一个人 不 希望只使用Node.js的,有什么用Node.js的发挥更好?Apache还是Nginx? 问题答案: 将另一个Web服务器放在Node.js前面有几个充分的理由: 不必担心Node.js进程的特权/ setuid。通常只有root可以绑定到端口80。如果让nginx / Apache担心以root身份启动,绑

  • 我想用selenium登录这个网页。我尝试了selenium的find_element_by_,并使用浏览器中的检查元素。但是我无法登录。我在搜索id、名称、类名,这样我就可以用send_keys传递数据,但是没有做到这些。有人能帮助我提供一些代码来将数据推送到所需的字段吗?谢谢。这就是我到目前为止所做的。 在此之后,我试图点击按钮登录使用 但它失败了。它给出了无法找到“登录”的错误。由于默认情况

  • 问题内容: 您好 ,我为编写的PHP代码所困扰。我盯着这个看了好几个小时都没有成功,请帮忙找出我显然已经解决的所有错误。 我想要此脚本执行的操作是从html表单页面中查询数据库表(“用户”)以确保其密码和用户名正确,然后在单独的表(“令牌”)中插入随机令牌(我以前使用过的方法,它可以正常工作)进入“ tk”列,然后用户进行常规身份验证。代码从“用户”表拉入“令牌”表中的“ gauth”列。 进行其

  • 我正在尝试将JSF Web应用程序与Spring Security集成。 目前我正在通过一种方法登录:在此方法中进行身份验证并根据用户重定向到目标页面。 登录页面(Login.xhtml): loginManagedBean。autenticar()(身份验证和重定向的方法): 如何替换此页面和方法以使用SpringSecurity? SpringSecurityConfig:

  • 问题内容: 我尝试将所有日志存储在哨兵实例中。相应于此线程,我尝试了以下操作: 将哨兵附加程序添加到loggin.yml: 和复制,并以ES / lib文件夹。启动过程中没有错误,但哨兵没有记录,即使在控制台上也有警告消息。ES的版本是2.1.0。 我想念什么吗? 问题答案: 这是有效的解决方案(适用于ES 2.4.4): 添加下面的库文件夹ES的:,,, 更新: 重新启动ES实例

  • 我有这个导入在我的文件app.spec.ts: 这导致了这个Typescript错误 。/app.ts确实存在,但是我没有编译。ts文件转换为. js文件。我一编译好。ts文件转换为. js文件,错误就消失了。 但是,由于eslint应该使用typescript,所以它应该使用。ts而不是. js。 我还在我的配置文件中添加了打字稿信息: 如何配置eslint以使其尝试用. ts而不是. js解析