Scrapy&验证码

时间:2015-01-14 16:55:00

标签: python scrapy captcha

我在网站https://www.barefootstudent.com/jobs中使用scrapy提交表单(任何指向页面的链接等http://www.barefootstudent.com/los_angeles/jobs/full_time/full_time_nanny_needed_in_venice_217021

我的scapy bot成功登录但我无法避免验证码。 对于表单提交,我使用scrapy.FormRequest.from_reponse

frq = scrapy.FormRequest.from_response(response, formdata={'message': 'itttttttt', 
                                   'security': captcha, 'name': 'fx',
                                   'category_id': '2', 'email': 'ololo%40gmail.com', 'item_id': '216640_2', 'location': '18', 'send_message': 'Send%20Message'
                                   }, callback=self.afterForm)

    yield frq

我希望从此页面加载验证码图像,并手动输入到脚本运行时。 等

captcha = raw_input("put captcha in manually>")  

我试试

 urllib.urlretrieve(captcha, "./captcha.jpg")

但是这种方法加载了不正确的验证码(网站拒绝我的输入)。我尝试在一个运行脚本中反复调用urllib.urlretieve,每次他返回不同的验证码时:(

之后我尝试使用 ImagePipeline 。 但我的问题是返回项目(下载图像)只有在函数执行完毕后才会发生,即使我使用了yeild。

 item = BfsItem()
 item['image_urls'] = [captcha]
 yield item
 captcha = raw_input("put captcha in manually>")  
 frq = scrapy.FormRequest.from_response(response, formdata={'message': 'itttttttt', 
                                   'security': captcha, 'name': 'fx',
                                   'category_id': '2', 'email': 'ololo%40gmail.com', 'item_id': '216640_2', 'location': '18', 'send_message': 'Send%20Message'
                                   }, callback=self.afterForm)
 yield frq

此时,当我的脚本请求输入时,图片不会下载!

我如何修改我的脚本并在手动输入验证码后调用FormRequest?

非常感谢!

3 个答案:

答案 0 :(得分:1)

我正在使用的方法通常效果很好(只是一个要点,你需要添加你的具体细节):

第1步 - 获取验证码网址(并保留表单的响应以供日后使用)

def parse_page_with_captcha(response):
    captcha_url = response.xpath(...)
    data_for_later = {'captcha_form': response} # store the response for later use
    return Request(captcha_url, callback=self.parse_captcha_download, meta=data_for_later)

第2步 - 现在scrapy将下载图像,我们必须在scrapy回调中正确处理

def parse_captcha_download(response):
    captcha_target_filename = 'filename.png'
    # save the image for processing
    i = Image.open(StringIO(response.body))
    i.save(captcha_target_filename)

    # process the captcha (OCR, or sending it to a decaptcha service, etc ...)
    captcha_text = solve_captcha(captcha_target_filename)

    # and now we have all the data we need for building the form request
    captcha_form = response.meta['captcha_form']

    return scrapy.FormRequest.from_response(captcha_form, formdata={'message': 'itttttttt', 
                               'security': captcha_text, 'name': 'fx',
                               'category_id': '2', 'email': 'ololo%40gmail.com', 'item_id': '216640_2', 'location': '18', 'send_message': 'Send%20Message'
                               }, callback=self.afterForm)

重要细节

受访保护的表单需要某种方式将验证码图像与查看并回答此验证码的特定用户/客户端相关联。这通常使用基于cookie的会话或隐藏在验证码表单中的特殊参数/图像标记来完成。

刮刀代码必须小心,不要破坏此链接,否则它将回答一些验证码,但不会回答它必须的验证码。

为什么不使用Verz1Lka发布的两个示例?

urllib.urlretrieve方法完全在scrapy之外工作。虽然这通常是一个坏主意(这不会使用scrapys调度等的好处),但主要问题是:此请求将完全在目标站点使用的任何会话cookie,url参数等之外工作。跟踪哪个验证码被发送到特定的浏览器。

另一方面,使用图像管道的方法在Scrapy的规则中很好地播放,但是这些图像下载计划在稍后进行,因此在下载时,验证码下载将无法使用。这是必要的。

答案 1 :(得分:0)

  

和手动输入到脚本运行时。等

本网站上的简单验证码可以通过任何优质的ocr服务自动解决,例如免费ocr.space api(使用“韩语”表示最佳数字ocr):

enter image description here

另一种方法是使用免费的Kantu软件,web automation with built-in OCR

答案 2 :(得分:0)

您正在下载不同的验证码图像,因为您没有使用输入表格URL时收到的相同Cookie。 Scrapy自己管理cookie,所以最好使用scrapy下载图像。 https://doc.scrapy.org/en/latest/topics/media-pipeline.html