小远的java爬虫总结2016.11
第一次接触简书,感觉这个东西很好,可以在上面学习到很多知识,这个还是看见海飞(我的朋友IOS程序员)写了一个项目总结,我才发现简书这么好的,页面简洁漂亮,操作暴力简单,功能好用齐全.
今天,我也在这里写下我的本月项目总结,我觉得每个程序员每个月都应该坚持写项目总结,这样有利于自己的成长,有利于看到自己的不足,还可以把自己每个月遇到的难题分享给大家,如果解决的难题,说不定还会有大神协助你解决,这样又可以学习到新东西,因为这是一个开放的平台,大家可以在上面交流和分享,所以我准备以后每个月都写简书,当然,能不能坚持也要看我自己的定力.
这是我进新公司的第一个月,简单来说,我自己认为这是我java爬虫方向开始入门的第一个月,虽然我之前也做过抓数据,但是之前做的是一个很小很小的功能,唯一的难点就是正确的用他的方式模仿请求去拿到数据,有些网站用get发送请求的很简单,半个小时就可以吧数据抓出来,有些网站很复杂,又通过URL传数据又通过request传数据,这个就很麻烦了,而且有些藏得很深,还会有cookies在变,这个就让我很头疼了.
不多扯淡了,说点正经的,这个月呢,刚刚进公司一般刚进公司嘛,都是先了解业务开始,了解了几天的业务后呢,开始安装logstash,虽然我现在还没有用过这个,也不是很了解这个东西,但我觉得用一次应该就会了,熟能生巧,只有多用才能轻车熟路,老大呢,还给我写了一个叫做selenium的东西,这个东西很厉害的啊,我很稀饭啊,selenium很强大,他是一个自动化测试用的东西,但是呢还可以拿来爬数据,爬电影,甚至还可以拿来爬羞羞的东西,当然这不是全部,还可以拿来做自动登录,有些视频,还可以用这个拿来刷播放量,还可以刷一些用cookies来判断的投票,我认为还可以拿来秒杀宝贝,当然我还没有写过秒杀,PS:当然12306的火车票就别想了,那个验证码的难度,只有买过票的人才知道,不做火车只做飞机的土豪当我没写。还可以做很多东西,这些只是我想到的,我自己还写了一个126邮箱的登录,自动登录我的邮箱,查看未读邮件。还爬了9大网络资源的数据
介绍几个比较重要的,我用的是selenium-server-standalone-3.0.0-beta2.jar,一个自动化的浏览器爬虫
首先爬的是爱奇艺,进入爱奇艺的movieList界面,建议先写分页抓数据,这样写代码的时候会很清晰,不然看上去就回很乱有时候上个厕所回来就不知道自己写到哪里了,写上URL,打开浏览器(我用的是chrome),部分网站打开chrome后,如果不滑动下拉选到最下面的话是选择不到下一页的,当然,只是部分,选择下一页建议用by.linkText("下一页")去获取元素,如果跳转几页就报了WebDriverException的话,那么就不要用这种方式了。使用定位className的方式去获取元素,有时候上一页的className和下一页的className会出现相同的状况,就会出现点击了下一页到了第二页,然后又点击上一页这样的无限循环的状态,为了避免这种状态,可以通过判断className的数量来避免,分页完成后写movieList界面,一般使用层级定位,先定位到movieList面板上,使用层级定位的方式一层一层的定位,这样运行的时候定位元素速度快,但是也有缺点,就是页面稍微有变动或者是两个电影页面有一个信息不全,或者是格式有一点点的不一样,就会报错,具体情况看页面。爱奇艺还有一个就是自动获取影片评论的话,需要滑动滚动条到下面才会加载评论,不然是不会加载评论的,这样的话定位元素就会NoSuchException,解决办法就是滑动滚动条,具体下面会有介绍。
还有土豆,如果要爬土豆的数据呢,需要先拿到他的hrefA,拿到hrefA后进入这个hrefA,进入后里面还需要再拿一个hrefB才能到达他的Info界面,我最开始就是用这样的,但是发现运行时间很长,效率很低,于是我就想优化一下,我从页面上找到了他的hrefA后和hrefB进行对比发现,两个href开头是差不多的,只用中间还有后面有部分差异,多对比了几个href,发现有部分hrefA还有特殊格式,这个时候就靠写代码来将hrefA直接转换成hrefB了,这样中间就不用进入hrefA了,节省了一个网站的加载时间,这样效率就大大提高了,我抓取土豆最开始需要半个小时以上,有时候还会报TimeoutException,经过这样处理后,时间直接缩短到了14.30min,虽然直接进入hrefB也有时候会报TimeoutException,但是相比之前那种做法效率就提高了很多.还有就是土豆采用的并不是分页的做法,而是采用滚动条下滑,然后下一页自动加载的方法,所以做分页的时候,只有拖动自己的滚动条下滑实现加载下一页,拖动浏览器滚动条selenium好像现在还没有,反正我是没有找到,于是我使用了模拟键盘输出space键来实现滚动条的滑动,
WebElement intro = driver.findElement(By.xpath("//a[@class='progInfo_detail_btn']")); //定位该元素
intro.sendKeys(Keys.chord(Keys.SPACE)); //对其元素进行space操作
intro只能是定位的元素的按钮或者悬浮加载div框,如果不是那就会WebDriverException,代表就是操作不可用。
最后说下有些页面格式,有些页面他的格式是ul下面有多个li,每一个li代表的是一条信息,比如导演是谁,有可能这部影片没有导演属于导演未知,那么就会少一个li按照一层不变的方式去抓取就会IndexOutOfBoundsException,所以,页面有变化,建议一个不是大的DIV框可以全部抓取下来后当做String 字符串去处理,这样抓到的信息会准确一点,不然就会有可能电影名写到导演上面,导演写到演员上,出现这样一种错位的情况。爬数据的就这么多了。。。。。。
代码写好了后,将他打成JAR包部署到win7环境下启动定时任务,天呐,我从来没有部署过win7 啊,但是查阅了一些资料后,发现也不是很难,只是和Linux还是有一点不同,打JAR包的时候选择Runnable JAR file,Launch configuration 这个选择项目的main方法所在的目录,Export destination 这个选择自己所希望保存到目录,Library handling:(这个目录下有三个选项,每个选项有不同的用处,当然其他两个我也木有用过),选择·Copy required libraries into a sub-folder next to the generated JAR,完成之后找到目录,直接就可以打开JAR包了,就像在eclipse中运行一样的,然后想要启动定时呢,需要自己写一个bat脚本文件去指向JAR包,内容很简单java -jar E:\aaa.jar ,在win中敲taskschd.msc打开任务计划程序创建基本任务,注意,选择文件的时候要选择自己写的bat脚本文件,下面还有个起始于,这个要写bat的目录,列:
脚本或程序: D:\seleniumTest\demo.bat
起始于: D:\seleniumTest\
如果没写起始于,那么运行的时候就会出现错误(0x1),(PS:在Win中(0x0)代表的是操作成功,(0x1)代表的是调用的函数不正确或调用了未知函数,这里就是属于调用的未知函数,(0xa)代表的是环境不正确,可以看看自己的JDK的环境变量是否安装规范,(0x8009000f)代表的是无法访问或者是拒绝访问,可能是文件破损或者是写有保护),写好了之后你创建的任务就会出现在进程列表里面显示状态为准备就绪,可以手动运行和自动运行,点击右边的运行进行手动运行,如果成功的运行了代码出现了想要的效果,那么定时任务就启动成功了,点击运行后会出现一个taskeng.exe的运行框拿来输出日志,如果工程很大很复杂的话,可以考虑分为两个JAR同时跑(也就是两个进程同时跑),提高效率。
我比较菜,请大家随意吐槽,有吐槽才有成长,谢谢大家!!!