前言
最近接了一个爬虫的私活,收益颇丰。自认为对爬虫掌握的还算不错,爬过很多国内外网站,数据超过百万,应对过封 IP、设验证码、假数据、强制登录等反爬虫手段。于是乎,我毫不犹豫的接下了该活。
但是进行了一半,我遇到了困难,写这篇文章希望能够找到感兴趣的朋友一起解决,一起分享劳动成果。如果到期没有解决的话,就当一次经历记录一下也罢。
项目需求
一个类似百度文库的网站,要求给出 url, 获得文章,以 Word 形式保存下来。保持格式不变。
我的进展和思路
我以前爬数据都是以文本的形式获得数据,然后清洗,保存数据库。但是这次需要保存到 word, 这不难,难在要求格式不变。我打算根据元素的 css 属性, 设置在 word 里面的格式。
获取文本
首先我使用我最熟悉的 python+selenium+chrome 组合,无头模式启动不用打开浏览器比较方便
def open_brower_headless():
chromeOptions = webdriver.ChromeOptions()
chromeOptions.add_argument(“headless”)
browser = webdriver.Chrome(chrome_options=chromeOptions)
return browser
文章部分是一个 iframe 框,通过 selenium 的 switch_to_frame() 方法切换到 iframe 元素,然后就是一系列的定位取值操作,很容易的取到了文章的文本。文章都是以许多 <p> 标签组合在一起的。通过绝对定位控制格式。(爬虫手法详情 https://segmentfault.com/a/11…)
我利用 selenium 的 value_of_css_property() 方法可以获得元素的属性 (font-family、top、font-size),这个方法比较强,不仅可以获得行内样式的 css, 还可以获得外嵌式的 css, 所以我不用担心它的样式写在 css 文件里。这样每一行的格式我就得到了。
1. 怎么换行?对比该元素和上一个元素的 top 属性的值,如果不一样就换行,高度不一样必定不在一行,很合理。2. 文字大小?元素的 font-size 的大小换算公式 ($/14 +0.5), 差不多匹配 docx 里面的 run.font.size 的值
docx 写入 word
python 库里面操作 word 使用的是 docx,docx 对 word 的读写有一套完整的方法。比如:添加文字,设置字体,颜色,大小,段落,表格,添加图片。docx 的使用也非常简单,主要分为三级:file >paragraph >run,下面简单介绍一下:
file = docx.Document() #新建文件
f = file.add_paragraph(“ 添加段落 ”) #添加段落
run = f.add_run(“ 追加文字 ”) #追加文字
run.font.color.rgb = RGBColor(0,0,1) #设置字体颜色
run.font.size = Pt(36) #设置字体大小
run.font.name = “ 宋体 ” #设置字体
run._element.rPr.rFonts.set(qn(‘w:eastAsia’), ‘ 宋体 ’)
run.add_break() #换行
file.save(“d.docx”) #保存文件
至今进度
如此我完成了一个简单 word 的爬取和保存。
瓶颈
但是我遇到了更复杂的问题,就是表格。F12 后发现表格的边框就是一个图片! 至此我不知道怎么进行下去了。开始我以为识别图片后我可以利用 doxc 插入表格,根据文字的位置,插入在对应的表格里,但是我发现有的文章还有其他图片。所以我不能遇到图片就将下面的文字按照表格里面的文字处理。
其他办法
发现这条路似乎走不通后,我试了其他办法,就是 pandoc, 这是一个文档转化工具,windows 下安装后通过输入命令来转化文档。比如将 a.html 转化为 b.docx
pandoc -s a.html -o b.docx
但是得到得 word 格式还没有我上面程序写的好,应该是我不太会用,网上对 pandoc 评价很高,几乎神器。我尝试将 html 先转化为 pdf, 然后再转 word. 但是失败了,需要安装 pdf 引擎,而且需要配中文之类的,总之我没有成功,不知道转化成 pdf 后再转化 word 它能否识别并插入表格。而不是背景图。知情人请告知,感激不尽。
我发现文章结构的 class 名和百度文库里的一样,这是通过百度富文本编辑器编辑的吧?,如果是这样通过这个富文本编辑器反编辑一下是否可行?
后面的话
距离项目测试版交期还有 3 天,搞不定这个问题话就黄了,如果有朋友能够解决或者有思路的话可以一起完成,报酬四位数。一起吃鸡,真不舍得放弃!