Scrapy中的Captchas

时间:2011-07-11 05:21:42

标签: python captcha scrapy

我正在开发一个Scrapy应用程序,我正在尝试使用使用验证码(不是垃圾邮件)的表单登录网站。我正在使用ImagesPipeline下载验证码,我将其打印到屏幕上供用户解决。到目前为止一切都很好。

我的问题是如何重新启动蜘蛛,提交验证码/表格信息?现在我的蜘蛛请求验证码页面,然后返回包含验证码Item的{​​{1}}。然后由image_url处理/下载,并显示给用户。我不清楚如何恢复蜘蛛的进展,并将解决的ImagesPipeline和同一个会话传递给蜘蛛,因为我相信蜘蛛必须在ImagesPipeline开始工作之前返回项目(例如退出)。

我查看了文档和示例,但我没有找到任何明确说明如何实现这一点的方法。

2 个答案:

答案 0 :(得分:5)

这就是可能让它在蜘蛛内部工作的方式。

self.crawler.engine.pause()
process_my_captcha()
self.crawler.engine.unpause()

收到请求后,暂停引擎,显示图像,阅读用户信息和信息。通过提交登录POST请求来恢复爬网。

我有兴趣知道这种方法是否适用于您的情况。

答案 1 :(得分:3)

我不会创建一个Item并使用ImagePipeline。

import urllib
import os
import subprocess

...

def start_requests(self):
    request = Request("http://webpagewithcaptchalogin.com/", callback=self.fill_login_form)
    return [request]      

def fill_login_form(self,response):
    x = HtmlXPathSelector(response)
    img_src = x.select("//img/@src").extract()

    #delete the captcha file and use urllib to write it to disk
    os.remove("c:\captcha.jpg")
    urllib.urlretrieve(img_src[0], "c:\captcha.jpg")

    # I use an program here to show the jpg (actually send it somewhere)
    captcha = subprocess.check_output(r".\external_utility_solving_captcha.exe")

    # OR just get the input from the user from stdin
    captcha = raw_input("put captcha in manually>")  

    # this function performs the request and calls the process_home_page with
    # the response (this way you can chain pages from start_requests() to parse()

    return [FormRequest.from_response(response,formnumber=0,formdata={'user':'xxx','pass':'xxx','captcha':captcha},callback=self.process_home_page)]

    def process_home_page(self, response):
        # check if you logged in etc. etc. 

...

我在这里做的是导入urllib.urlretrieve(url)(以存储图像),os.remove(file)(删除上一张图像)和subprocess.checoutput(调用外部命令行)实用程序解决验证码)。整个Scrapy基础设施并没有在这个“黑客”中使用,因为解决像这样的验证码总是一个黑客。

整个调用外部子进程的东西可能是一个更好的,但这是有效的。

在某些网站上,无法保存验证码图像,您必须在浏览器中调用该页面并调用screen_capture实用程序并在确切位置裁剪以“剪切”验证码。现在这就是屏幕抓图。