如何设置Scrapy来处理验证码

我正在尝试抓取一个要求用户输入搜索值和验证码的网站。我有一个用于验证码的光学字符识别(OCR)例程,该例程成功完成了大约33%的时间。由于验证码始终是字母文本,因此如果OCR函数返回非字母字符,我想重新加载验证码。输入文字“ word”后,我想提交搜索表单。

结果返回到同一页面,表格已准备好进行新的搜索和验证码。因此,我需要冲洗并重复直到我用尽搜索词。

这是顶级算法:

  1. 最初加载页面
  2. 下载验证码图片,通过OCR运行
  3. 如果OCR没有返回纯文本结果,请刷新验证码并重复此步骤
  4. 提交包含搜索词和验证码的页面中的查询表单
  5. 检查响应以查看验证码是否正确
  6. 如果正确,请抓取数据
  7. 转到2

我尝试使用管道来获取验证码,但是后来我没有表单提交的价值。如果我只是使用urllib或其他方法获取图像而不通过框架,则不会提交带有会话的cookie,因此服务器上的验证码验证失败。

这样做的理想的Scrapy方式是什么?

回答:

有很多解决方案是一个非常深入的话题。但是,如果你想应用在帖子中定义的逻辑,则可以使用scrapy Downloader Middlewares。

就像是:

class CaptchaMiddleware(object):

max_retries = 5

def process_response(request, response, spider):

if not request.meta.get('solve_captcha', False):

return response # only solve requests that are marked with meta key

catpcha = find_catpcha(response)

if not captcha: # it might not have captcha at all!

return response

solved = solve_captcha(captcha)

if solved:

response.meta['catpcha'] = captcha

response.meta['solved_catpcha'] = solved

return response

else:

# retry page for new captcha

# prevent endless loop

if request.meta.get('catpcha_retries', 0) == 5:

logging.warning('max retries for captcha reached for {}'.format(request.url))

raise IgnoreRequest

request.meta['dont_filter'] = True

request.meta['captcha_retries'] = request.meta.get('captcha_retries', 0) + 1

return request

此示例将拦截每个响应并尝试解决验证码。如果失败,它将重试该页面以获取新的验证码;如果成功,它将添加一些元密钥以响应已解决的验证码值。

在蜘蛛中,你可以这样使用它:

class MySpider(scrapy.Spider):

def parse(self, response):

url = ''# url that requires captcha

yield Request(url, callback=self.parse_captchad, meta={'solve_captcha': True},

errback=self.parse_fail)

def parse_captchad(self, response):

solved = response['solved']

# do stuff

def parse_fail(self, response):

# failed to retrieve captcha in 5 tries :(

# do stuff

以上是 如何设置Scrapy来处理验证码 的全部内容, 来源链接: utcz.com/qa/434342.html

回到顶部