python - 在 CrawlSpider 中将 cookie 传递给后续请求

标签 python python-3.x selenium scrapy

我正在尝试从桥牌网站上抓取最近锦标赛的一些结果。我之前发布了一个关于这个的问题 here .感谢@alecxe,我在使用 PhantomJS 在页面上呈现一些 JavaScript 时让爬虫登录。

我的理解是,我使用 selenium 登录,将凭据保存在 cookie 中,然后将 cookie 传递给普通的 CrawlSpider 以获取身份验证完成,从而绕过 InitSpider 的问题。这对于初始登录页面来说效果很好,但是一旦爬虫进入 Rule 定义的下一个页面,网站就会把我踢出去。它只是再次抓取登录页面。

为了解决这个问题,我尝试将 cookie 保存在全局变量中并覆盖 make_requests_from_url() 以将 cookie 传递给蜘蛛发出的所有后续请求。但它仍然返回登录页面的主体。

问题:这里发生了什么?我从某个地方听说,一旦您将 cookie 传递给 start_requests(),那么 cookie 应该会在 CrawlSpider session 的其余部分持续存在。但它显然不会那样做。谁能告诉我在哪里可以看到 Scrapy 如何处理这个问题?

我的代码:

import scrapy
from scrapy.spiders import Rule
from scrapy.linkextractors import LinkExtractor
from scrapy.http import Request, HtmlResponse

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.spiders.CrawlSpider):
    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):
        global bbo_cookies

        driver = webdriver.PhantomJS()
        driver.get(self.login_page)    
        driver.find_element_by_id("username").send_keys("_____")
        driver.find_element_by_id("password").send_keys("_____")
        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")))

        bbo_cookies = driver.get_cookies()
        driver.close()

        yield Request("http://webutil.bridgebase.com/v2/tarchive.php?m=h&h=acbl&d=ACBL&o=acbh", cookies=bbo_cookies)

    def make_requests_from_url(self, url):
        request = super(BboSpider, self).make_requests_from_url(url)
        request.cookies = bbo_cookies
        return request

    rules = [ 
            Rule(LinkExtractor(allow=r'tourney=4796-1455303720-'), callback='parse_item', follow=True),
            ]

    def parse_item(self, response):
        print(response.body)

日志的准系统相关部分(目前)并没有透露太多有趣的内容。如有必要,我可以提供更多详细信息。

2016-02-13 09:31:04 [scrapy] INFO: Enabled item pipelines:
[]
2016-02-13 09:31:04 [scrapy] INFO: Spider opened
2016-02-13 09:31:04 [scrapy] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min)

[... bunch of Selenium messages ...]

2016-02-13 09:31:13 [scrapy] DEBUG: Crawled (200) <GET http://webutil.bridgebase.com/v2/tarchive.php?m=h&h=acbl&d=ACBL&o=acbh> (referer: None)

[... more Selenium messages ...]

2016-02-13 09:31:16 [scrapy] DEBUG: Crawled (200) <GET http://www.bridgebase.com/myhands/hands.php?tourney=4796-1455303720-> (referer: http://webutil.bridgebase.com/v2/tarchive.php?m=h&h=acbl&d=ACBL&o=acbh)
2016-02-13 09:31:17 [scrapy] INFO: Closing spider (finished)
2016-02-13 09:31:17 [scrapy] INFO: Dumping Scrapy stats:

很明显,我不太了解 scrapy 的工作原理。

最佳答案

看起来你的正则表达式不正确......你将搜索限制在那个......

rules = [ 
'''
...allow=r'tourney=4796-1455303720-' 
'''
]

'#TO DO:修正你的正则表达式...

它实际上只是被允许为锦标赛搜索特定的 id ...,您还应该在您的链接规则中包含斜杠 ...

你所拥有的正则表达式...

"allow=r'tourney-id=123'
tourney-id=123 ... FOUND IT! MATCHES THE ASLLOW RULE;
tourney-id=456 ...- NOPE, NOT ALLOWED
tourney-id=789... NOPE! BOT ALLOWED... YOU DONT LET DO NUFIN!

所以你看到你在那里做了什么?

虽然我没有复制您的脚本,但在我看来非常干净...除了正则表达式处理之外,如此精良的逻辑但缺少正则表达式?大声笑我确定这只是一个疏忽,所以我不会质疑你的技能...写得很好的代码,我必须相信你知道你的规则。

如果您确实需要这方面的帮助,请告诉我,

-Scriptso

PS 我真的只是认真对待最终投身于这个社区,过去 3 年有一对反对票。如果您发现我有任何帮助,请给我点赞好吗?!哈哈

编辑!

出于好奇,我正在运行你的脚本,它并不像我想象的那么干净,起初看起来合乎逻辑(我自己阅读了明显的错误)但是就跟踪而言有很多错误回到错误日志让我最初相信这是一个非常干净的执行,但事实是它完全不正常......首先......

class BboSpider(scrapy.spiders.CrawlSpider):

当你定义你的蜘蛛类时,它是一个或另一个......scrapy.spider,或 CrawlSpider,或一个客户构建,但无论哪种方式都是派生的......或另一个大声笑
取决于您的选择... 使用爬行蜘蛛你最终不得不在 items.py 中定义你的项目......你没有要求只是运行打印的项目? 爬虫......虽然除了做正确的事情以逐项列出项目之外并没有真正的需要,如果你打算使用爬虫那么你得 定义项目类

YourItems(item):
item1 = Field()
etc etc...

我可以建议你每次启动一个你使用的 scrapy 项目(你可能已经使用过)时使用 scrapy startproject arg。我现在真的做了一个 180 并且假设你复制并粘贴了大部分内容???事实上,看起来你把 2-3 个 LMAO 一起砸了,没关系!我们都从某个地方开始,但通过艰苦的方式学习是很好的……有效的……

对于您尝试做的事情,您不必合并 Selenium ...已经是一个完全不同的野兽,而是在提升您的 python 技能之前承担较小的任务(scrapys 逻辑框架 + 模块之间有一个珊瑚使用和对 python 工作原理的理解水平..我不是专业人士,但我已经过了菜鸟)

您应该使用什么? 我建议使用 ForumRequest 选项简单地请求模块...简单登录就可以了...

使用 Selenium 很酷,除了需要携带 cookie 之外,实际上它必须掌握 selenium 的窍门,这是一项艰巨的任务,因为它是一个非常繁重的模块,但如果你愿意,你一定要学习它。 ...您不必自杀...SOO!...

如果你需要帮助,我会在这里,给我发消息,学习点点滴滴的一半满足感(也是生活中的吸吮,社会耻辱的部分......我真是个 fn nerd #facepalm)这就是学习新的东西,但一次采取它,如果一般的经验法则......如果你的古纳使用库,模块,任何语言的扩展......在处理复杂的东西之前了解它的来龙去脉...... .

关于python - 在 CrawlSpider 中将 cookie 传递给后续请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35381311/

相关文章:

python - 在 Python matplotlib 中更改 X 轴步长

python-3.x - 这个换币组合算法的时间复杂度是多少?

python - 调用 print 时是否导入了 sys 'temporarily'?

Python Selenium 获取变量中的 HTML 文本

python - Selenium 浏览器自动化 session 在等待 7 分钟时过期

python - 在 Django 中获取查询对象的外键值

python - 如何获取Opennebula XML-RPC api需要的参数

python-3.x - 如何在Python中将TensorBoard与Keras结合使用以可视化嵌入

python - 错误消息 - 元素不可交互的 Selenium webdriver

python - tkinter 中不可移动的文本