大概是两个月之前,有同学问我能不能爬一下大众点评页面的店铺名称、评分什么的信息,当时尝试了一下,发现很多文字和数字都被替换成了svg,据说是css加密,因为要考cpa,所以就一直搁置了。
前不久看到了matplotlib绘制字体的教程,就在想能不能OCR识别,结果画出来的字根本就不能看,直到昨天看到了一篇用PIL绘制字体,然后用pytesseract破解大众点评反爬的教程……
参考链接:https://blog.csdn.net/weixin_43752839/article/details/98314821
原作者实在是太牛了。
我也抄了一份过来,加在了scrapy的下载中间件里,这样就可以直接得到解密后的response:
from scrapy import signals from urllib.parse import urljoin from urllib.request import urlretrieve from PIL import Image, ImageDraw, ImageFont from fontTools.ttLib import TTFont from scrapy.http.response.html import HtmlResponse import requests, numpy, pytesseract, re class DzdpDownloaderMiddleware(object): def process_response(self, request, response, spider): # 判断是否css加密,若是,则尝试解密 if "svgtextcss" in response.text: try: response1 = HtmlResponse(url=response.url, body=self.svg_to_text(response), request=request, encoding='utf-8') return response1 except: return response else: return response # 构建新的response def svg_to_text(self, response): text = response.text headers = { "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36" } # 获取css的链接 css_url = urljoin('https://', response.xpath('//link[contains(@href, "svgtextcss")]/@href').get()) # 请求css文件 r = requests.get(css_url, headers=headers) # 获取字体链接 woff_list = re.findall('url\("([A-Za-z0-9._\/]*woff)\"?', r.text) # 创建字体解密字典 replace_dict = dict() for woff in woff_list: woff_url = urljoin('https://', woff) fontPath = 'font.woff' urlretrieve(woff_url, fontPath) svg = self.fontConvert(fontPath) replace_dict.update(svg) for i in replace_dict.items(): text = text.replace(i[0], i[1]) return text # woff字体转文本,参考https://blog.csdn.net/weixin_43752839/article/details/98314821 def fontConvert(self, fontPath): font = TTFont(fontPath) codeList = font.getGlyphOrder()[2:] im = Image.new("RGB", (1800, 1000), (255, 255, 255)) dr = ImageDraw.Draw(im) font = ImageFont.truetype(fontPath, 40) count = 15 arrayList = numpy.array_split(codeList,count) for t in range(count): newList = [i.replace("uni", "\\u") for i in arrayList[t]] text = "".join(newList) text = text.encode('utf-8').decode('unicode_escape') dr.text((0, 50 * t), text, font=font, fill="#000000") result = pytesseract.image_to_string(im, lang="chi_sim") result = result.replace(" ","").replace("\n","") codeList = [i.replace('uni', '&#x')+';' for i in codeList] return dict(zip(codeList,list(result)))
不过这样也带来了效率问题,网上好像有人调用了百度OCR的API,不过我感觉最好是把之前识别的保存在本地,在OCR之前先判定一下是不是已经有了识别的结果,这样效率会更高。
我太懒了,不想再做了,至于是判断url还是判断ttfont的结果,就留给真正需要的人自己去折腾吧。
至于只能查看第一页的反爬措施,直接登录一下,然后在settings里面加上cookies就好。
最后尝试用一下SQL,我才发现我连插入语句都忘了,哈哈哈我还真敢在简历里写上会用SQL增删查改啊……
Comments | NOTHING