简单记录最近遇到的验证码问题(2020-03-23)
-
工具
selenium+webdriver+Python3+斐斐打码
-
背景
访问数据需要输入验证码,点击确认,才能返回数据。
-
爬虫进行思路
模拟登陆==》自动截图验证码==》识别验证码(借助打码平台)》模拟输入,点击提交确认》提取数据
-
直接上代码
‘’’
def parse(self, response): url = "这里是验证码所在页面网址" chrome_options = Options() chrome_options.add_argument('--headless') # 无头模式 chrome_options.add_argument('--disable-gpu') # 谷歌文档提到需要加上这个属性来规避bug chrome_options.add_argument('--no-sandbox') # 以最高权限运行 chrome_options.add_argument("--test-type") chrome_options.add_argument( 'user-agent="MQQBrowser/26 Mozilla/5.0 (Linux; U; Android 2.3.7; zh-cn; MB200 Build/GRJ22; CyanogenMod-7) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1"') driver = webdriver.Chrome(chrome_options=chrome_options) driver.get(url) driver.save_screenshot('全屏截图.jpg') verif = response.xpath('//*[@id="verifycode"]/@src').extract() # 这里对验证码是否存在进行判断(如果之前已经登录,短时间内不用再次填写验证码) if len(verif) > 0: # 这里我们调用selenium+webdriver自动化截图工具 # 比如获得ID名为verifycode的元素截图 # 首先要等待他加载出来2秒一次 screen = WebDriverWait(driver, 2, 1).until(EC.presence_of_element_located((By.ID, 'verifycode'))) # 获取元素保存 # img = driver.find_element_by_id('verifycode').screenshot() img = driver.find_element_by_id('verifycode').screenshot('yzmjt.jpg') time.sleep(3) driver.find_element_by_name("verifycode").clear() # 清空原关键字 time.sleep(3) driver.save_screenshot('0.jpg') # 借助打码平台,这里我用的是斐斐打码。PredictFromFileExtend指的是传入文件。 # 40400是是识别类型(40400代表四个汉字) # (app_id, app_key, pd_id, pd_key)自己买啊 yzm = FateadmApi(app_id, app_key, pd_id, pd_key).PredictFromFileExtend(40400, "yzmjt.jpg", ) print(yzm) # 判断验证码识别情况,存在失败情况,失败则重新识别 if len(yzm) == 4: driver.find_element_by_name("verifycode").send_keys(yzm) # 填入验证码 time.sleep(10) driver.save_screenshot('1.jpg') driver.find_element_by_class_name('enquiries').submit() # 提交验证码 time.sleep(10) driver.save_screenshot('2.jpg') time.sleep(10) driver.save_screenshot('3.jpg') time.sleep(10) # driver.close() # 只会关闭当前焦点所在的窗口 driver.quit() # 会关闭所有关联窗口和session,并且也会把进程也关闭 yield scrapy.Request(url, callback=self.parse_item, dont_filter=True) else: # 可以做尝试机制,失败超过三次就停止 yield scrapy.Request("我这里随意指定百度网址", callback=self.parse, dont_filter=True) else: yield scrapy.Request(url, callback=self.parse_item, dont_filter=True)
‘’’
这里我们调用selenium+webdriver自动化截图工具(参考https://www.cnblogs.com/pythonywy/p/11777511.html)
driver.find_element属性识别参考https://www.cnblogs.com/zhuque/p/8321481.html
-
这里贴几个上面的截图
全屏截图.jpg(这里我裁剪了,原图是一个首页)
这里是yzmjt.jpg
-
进行到这里,一般情况我们就可以采集数据了,但是也有额外的情况,有的网站需要验证码登录进去之后,抓取cookie,然后携带cookie才能进行之后的访问,这里就不做介绍了(个别网站反爬比较厉害,抓下来的cookie会失效)
-
简单的验证码我们python是可以自己简单识别的,明天再介绍一个识别数字验证码的截图。python+PIL+Pytesseract