2016-08-25 15 views
10

Tôi đang cố gắng xóa một trang web yêu cầu người dùng nhập giá trị tìm kiếm và hình ảnh xác thực. Tôi đã có một thói quen nhận dạng ký tự quang học (OCR) cho captcha thành công khoảng 33% thời gian. Vì captchas luôn là văn bản chữ cái, tôi muốn tải lại hình ảnh xác thực nếu hàm OCR trả về các ký tự không phải chữ cái. Khi tôi có một từ "văn bản", tôi muốn gửi mẫu tìm kiếm.Làm cách nào để thiết lập Scrapy để xử lý hình ảnh xác thực

Kết quả trở lại trong cùng một trang, với biểu mẫu sẵn sàng cho tìm kiếm mới và hình ảnh xác thực mới. Vì vậy, tôi cần phải rửa sạch và lặp lại cho đến khi tôi đã cạn kiệt cụm từ tìm kiếm của mình.

Dưới đây là các thuật toán cấp cao nhất:

  1. trang tải ban đầu
  2. Tải hình ảnh captcha, chạy nó thông qua OCR
  3. Nếu OCR không quay trở lại với một văn bản chỉ dẫn , làm mới hình ảnh xác thực và lặp lại bước này
  4. Gửi biểu mẫu truy vấn trong trang có cụm từ tìm kiếm và hình ảnh xác thực
  5. Kiểm tra phản hồi để xem hình ảnh xác thực có chính xác không
  6. Nếu nó là đúng, cạo dữ liệu
  7. Đến 2

Tôi đã cố gắng sử dụng một đường ống dẫn để nhận được mã xác nhận, nhưng sau đó tôi không có giá trị cho việc nộp đơn. Nếu tôi chỉ cần lấy hình ảnh mà không đi qua khung, sử dụng urllib hoặc một cái gì đó, sau đó cookie với phiên không được gửi, do đó xác thực captcha trên máy chủ không thành công.

Cách lý tưởng để làm việc này là gì?

Trả lời

7

Đó là một chủ đề thực sự sâu với một loạt các giải pháp. Nhưng nếu bạn muốn áp dụng logic mà bạn đã xác định trong bài đăng của mình, bạn có thể sử dụng số ít Downloader Middlewares.

Cái gì như:

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 

Ví dụ này sẽ chặn tất cả các câu trả lời và cố gắng giải quyết vấn captcha. Nếu không thành công, nó sẽ thử lại trang cho hình ảnh xác thực mới, nếu thành công, nó sẽ thêm một số khóa meta để phản hồi với các giá trị captcha được giải quyết.
Trong nhện của bạn, bạn sẽ sử dụng nó như sau:

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 
Các vấn đề liên quan