c爬虫抓取网页数据( 利用PIL包的crop函数得到标签大小将标签剪切保存)
优采云 发布时间: 2021-12-22 23:18c爬虫抓取网页数据(
利用PIL包的crop函数得到标签大小将标签剪切保存)
contents_list = driver.find_elements_by_css_selector('dl.board-wrapper dd')
注意这里我们使用的是 find_elements_by_css_selector,并且在元素之后添加了 s。如果不加s,find_element方法只能得到第一个节点。添加s后,可以得到所有满足条件的节点,并以列表形式返回。
获取label的文本内容也很简单,比如提取电影排名:
content['index']= content.find_element_by_css_selector('i.board-index').text
找到标签后,添加 .text 即可获取标签内容。获取标签中的属性值也很简单,比如提取电影名称:contents['title'] = content.find_element_by_css_selector('img.board-img').get_attribute('alt')
找到标签后,添加 .get_attribute('attribute name') 即可获取标签中的属性值。具体例子如下:
for content in contents_list:
contents['index'] = content.find_element_by_css_selector('i.board-index').text
; contents['image_url'] = content.find_element_by_css_selector('img.boardimg').get_attribute('src')
;contents['title'] = content.find_element_by_css_selector('img.boardimg').get_attribute('alt')
try:
contents['actor'] = content.find_element_by_css_selector('p.star').text
; except NoSuchElementException:
;contents['actor'] = ''
; contents['time'] = content.find_element_by_css_selector('p.releasetime').t;
3. 将票房信息保存为图片,使用PIL对图片进行二值化、锐化等预处理操作
保存要获取信息的标签图片的一般步骤如下:
a) 拦截当前窗口(selenium 不能直接拦截单个标签)
b) 获取标签位置坐标和标签大小
c) 使用PIL包的裁剪功能,根据标签的坐标和大小对标签进行裁剪保存
示例如下:
图片
上图是网页截图。使用 save_screenshot 函数获取当前窗口的屏幕截图。我们需要将票房数据裁剪保存在蓝框中,所以需要它们的坐标和大小。幸运的是,我们可以使用 .location 和。size函数获取标签的坐标和大小,最后使用PIL包的crop函数根据标签的坐标和大小对标签进行裁剪和保存。
上述步骤在第一屏捕获信息时非常有用,但是当窗口超过一个屏幕并且需要捕获的元素在后面时,您只能寻找其他方法。
来抓一下猫眼影业的电影票房网页,比较长,不能一屏显示。当然我们也可以用js把网页下拉然后截图,这样也可以截取下面网页的信息,但是获取到的标签位置坐标的参考点在网页的左上角(如上图),并且crop功能在裁剪时使用当前图片的左上角为基准,所以不同基准截取的内容肯定是错误的。
我在网上发现,WebDriver.PhantomJS的内置方法支持整个网页的截图,不是很爽,但是我用的时候就糊涂了。PhantomJS 可以拦截整个网页,但是拦截结果是这样的:
图片
我不能给尼玛什么?同时程序还提示警告selenium不再允许使用PhantomJS。让我们回去默默地使用 chrome。突然,灵光一闪。刚才不能用chrome的原因是location函数和crop函数得到的label坐标在裁剪坐标上是不同的。做吧,这个网页一共有10部电影。我只是下拉 10 次就可以了,所以这里我们有一个 for 循环。window.scrollTo 函数使用下拉网页。它有两个参数。第一个是代表水平方向的参数。要拖动的像素数,第二个代表要垂直拖动的像素数。但是你每次拉下来多少?270px(像素),
咦,你怎么知道?
告诉你一个我们使用微信截图的小技巧,它会显示截图图片的大小。对于这个例子,让我们每次拉下两个电影票房之间的长度。长度为270px,如下图所示。
图片
这样,您应该可以获取每个票房数据标签。得到票房数据标签后,我们需要进行图像预处理(二值化、锐化),最后保存标签。部分代码如下:
length = n*270driver.execute_script('window.scrollTo(0, {}*270)'.format(n))# 保存当前窗口为图片driver.save_screenshot('b.png')# time.sleep(2)# 定位div地址location = div.location# print(location)# 得到div尺寸size = div.size# print(size)left = location['x']top = location['y'] - lengthright = location['x'] + size['width']bottom = location['y'] + size['height'] - length
4. 使用tesseract识别保存的图片,获取票房数据
原票房数据图片:
图片
预处理后的票房数据图片:
图片
使用tesseract对处理后的图片进行识别,部分代码如下:
# 调用tesseract进行文字数字识别,目前对于浅颜色的字体识别率较低,若想提高识别率需要对图片做预处理os.system('echo off')#关闭命令行窗口运行命令的显示os.system('tesseract' + ' ' + filename + ' ' + output + ' ' + '-l num+chi_tra') #默认已配置好系统变量time.sleep(2)f = open(output + ".txt", encoding='utf-8')try: t = f.readlines()[0]
目前没有训练自己的数据识别包,直接使用tesseract已有的数据包,经过多次试验,实时票房识别率达到97%以上。由于总票房字体颜色偏浅,字体偏小,目前识别率还比较低,在60%左右。得到的数据如下图所示:
图片
这是第一次尝试使用图像识别来解决爬虫和到达问题。感觉真的很好玩。目前已经开放了获取标签图像的流程,但在图像预处理和图像识别方面还有很多工作要做。目前使用的是第三方软件Tesseract。-OCR识别,一方面我们会继续研究Tesseract-OCR,另一方面我们也会尝试使用深度学习的方法来提高图像文本的识别准确率。
图片