使⽤Java做爬⾍时遇到的⼏个坑
写在前⾯
最近项⽬⾥边需要在Java中使⽤爬⾍技术,原本打算⽤python写好爬⾍然后⽤Java来调⽤,但是在⽹上了许多Java调⽤python代码的⽅法,发现其中的⽤法都⼗分重量级,要不就把Jython解释器整个弄来,要不就直接在命令⾏运⾏python⽂件,这都不是我想要的。权衡再三后决定⽤Java把爬⾍重新实现⼀遍,不得不说,语⾔和语⾔之间的区别不是⼀点半点。下⾯是我在代码移植过程中遇到的⼏个坑:
javax.script包解析JS时出现的问题
要爬的⽹站在数据加密⽅⾯下了功夫,⽤户请求得到的数据都是密⽂,需要⽹站⾃带的JS代码进⾏解密,千⾟万苦把⽤来解密的JS代码扒出来后,使⽤python的execjs包完美运⾏~~将代码移植到Java上的时候,百度发现Java中有专门⽤来解析脚本⽂件的javax,script包,兴冲冲的直接⽤上,⼀运⾏,我蒙了,控制台飘红,JS运⾏出错了:
t.slice is not a function
吓得我赶紧看了看JS代码,没错啊,在python上完美运⾏的也是这代码,怎么换到Java上就不⾏了呢??
命名冲突?我赶紧把同名的变量全部改了名字,⼜⽤python运⾏了⼀遍,能够正常运⾏,再转到Java,期待能够解决,没料想不但没有解决,错误还多了⼏⾏…
本来就没有什么js经验的我顿时慌了阵脚,赶紧百度看看相关问题别⼈是怎么解决的,结果⽹上也多是⼀些⽜头不对马嘴的回答,⼏个⼩时就这么过去了,后来突然想到,会不会是t这个对象真的没有slice函数,但是不对啊,python上边都能运⾏,后边我还试了nodejs也⼀样能运⾏,怎么这⾥就不⾏了?但是我还是抱着试⼀试的⼼态搜了⼀下,原来还真有这么个说法,原来t这个对象的类是Uint8Array,其中的slice函数在某些环境下⽆法使⽤(⽐如安卓),但是他有⼀个替代函数subarray,可以完成相同的⼯作。把出错的地⽅的slice函数换为subarray之后代码运⾏成功…我也终于舒了⼀⼝⽓,谁能想到是这么个问题…话说为什么要实现两个功能⼀样的函数…难道是函数别名这种说法??
JS与Java交互的问题
这之后我还犯了⼀个⾮常蠢的错误,js代码中直接把js对象返回到java⾥边了,⾃⼰⼜不知道在Java中怎么解析这个js对象,于是疯狂的在⽹上Java解析JSONObject的⽅法,结果都是通过JSON字符串来创建的JSONObject…我⼜不知道该怎么办了,后来发现原来js中可以直接把JS对象转换成JSON字符串的函数:
JSON.stringify(value[, replacer[, space]])
看到这个函数之后直接想吐槽⾃⼰之前都在⼲嘛…(不过python与js交互的确没有这种步骤,js对象可以直接转换为python中的字典或者列表,它们俩相性真不是⼀般的好…)
Jsoup保留换⾏符问题
Jsoup是Java中的⼀个HTML解析包,其功能⾮常强⼤…所谓的soup,我觉得跟python中的BeautifulSoup有异曲同⼯之妙。不得不
说,Jsoup获取的HTML内部⽂本格式⾮常美丽,使⽤过python爬⾍的⼈知道,获取内部⽂本的⽅法⼀般都是text(),⽽这种⽅法返回的⼀般都是不加修饰的字符串或者字符串列表,其中乱七⼋糟的换⾏符制表符⼀⼤堆,⼗分影响观感。⽽Jsoup就不会有这种问题,使⽤Jsoup 提取⽂本,数据与数据之间使⽤⼀个⼩巧的空格隔开,⼗分优美,得到的字符串整洁⼲净,使⼈赏⼼悦⽬。我⼀边欣赏着提取到的美丽的字符串,⼀边按下debugger中的下⼀步,程序运⾏到下⼀个断点,这时我发现了⼀个问题:
我之前写好的正则表达式匹配不到东西了。。。
再确认正则表达式语法上没有出问题之后,我⼜看了看那优美的字符串,这时,我发现了问题的所在,我感觉有⼀个巨⼤的巴掌反复抽打着我的脸:
这个字符串没有换⾏符
什么意思?由于要爬的页⾯HTML结构的特殊性,我需要⽤到换⾏符\n对数据进⾏分段,但是Jsoup提取到的数据⾥边,竟然**没有换⾏符!!**不得不说Jsoup的这个功能真是华⽽不实,直接把数据的结构性给破坏了,这可坏事了,怎么办呢…
百度得到了答案:
Jsoup.clean(html, "", (), new Document.OutputSettings().prettyPrint(false));
python转java代码使⽤Jsoup.clean⽅法,并将最后⼀个参数设置为new Document.OutPutSettings().prettyPrint(false),于是得到的字符串⾥边就包含换⾏符了。
⾄此,将爬⾍从python转移到Java成功,万岁

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。