我在爬取页面的时候发现有很多数据是js渲染进去的,通过:
String htm = page.getHtml().xpath("*/html/html()").toString();
page.putField("html",htm);
就可以看到爬取下来的页面数据,可以很清晰的看出页面里面有没有自己想要的数据,如果没有,那么我们就需要进一步操作!
如果数据是ajax请求过来的,那么可以参考webmagic开发者的ajax爬取方法。我想爬取的页面数据是直接js渲染的,使用了
PhantomJ渲染之后爬取。
简单来说,PhantomJ就是一个网页浏览器。
当然我们也可以直接用谷歌浏览器代替PhantomJ,但会爬取很慢。
一:先讲一下谷歌浏览器怎么渲染爬取
用谷歌浏览器必须先下载一个谷歌的浏览器驱动,下载地址:http://chromedriver.storage.googleapis.com/index.html
要注意驱动对应谷歌版本:https://blog.csdn.net/llbacyal/article/details/78563992
demo:
package spider; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriverService; import org.openqa.selenium.remote.DesiredCapabilities; import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.support.ui.ExpectedCondition; import org.openqa.selenium.support.ui.WebDriverWait; import java.io.File; import java.io.IOException; /** * chromeDriver是谷歌的浏览器驱动,用来适配Selenium,有图形页面存在,在调试爬虫下载运行的功能的时候会相对方便 * @author zhuangj * @date 2017/11/14 */ public class TestChromeDriver { private static ChromeDriverService service; public static WebDriver getChromeDriver() throws IOException { System.setProperty("webdriver.chrome.driver","C:/Users/Administrator/AppData/Local/Google/Chrome/Application/chrome.exe"); // 创建一个 ChromeDriver 的接口,用于连接 Chrome(chromedriver.exe 的路径可以任意放置,只要在newFile()的时候写入你放的路径即可) service = new ChromeDriverService.Builder().usingDriverExecutable(new File("F:\\chromedriver.exe")) .usingAnyFreePort().build(); service.start(); // 创建一个 Chrome 的浏览器实例 return new RemoteWebDriver(service.getUrl(), DesiredCapabilities.chrome()); } public static void main(String[] args) throws IOException { WebDriver driver = TestChromeDriver.getChromeDriver(); // 让浏览器访问 Baidu driver.get("https://www.taobao.com/"); // 用下面代码也可以实现 //driver.navigate().to("http://www.baidu.com"); // 获取 网页的 title System.out.println(" Page title is: " +driver.getTitle()); // 通过 id 找到 input 的 DOM WebElement element =driver.findElement(By.id("q")); // 输入关键字 element.sendKeys("东鹏瓷砖"); // 提交 input 所在的 form element.submit(); // 通过判断 title 内容等待搜索页面加载完毕,间隔秒 new WebDriverWait(driver, 10).until(new ExpectedCondition() { @Override public Object apply(Object input) { return ((WebDriver)input).getTitle().toLowerCase().startsWith("东鹏瓷砖"); } }); // 显示搜索结果页面的 title System.out.println(" Page title is: " +driver.getTitle()); // 关闭浏览器 driver.quit(); // 关闭 ChromeDriver 接口 service.stop(); } } |
二:PhantomJ抓取
先下载一个PhantomJ,下载地址:http://phantomjs.org/download.html
linux安装方法:https://www.cnblogs.com/yestreenstars/p/5511212.html安装的时候注意最好是安装最新版本的可以从上面链接找最新版本号
demo:
package spider; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.phantomjs.PhantomJSDriver; import org.openqa.selenium.phantomjs.PhantomJSDriverService; import org.openqa.selenium.remote.DesiredCapabilities; /** * PhantomJs是一个基于webkit内核的无头浏览器,即没有UI界面,即它就是一个浏览器,只是其内的点击、翻页等人为相关操作需要程序设计实现; * 因为爬虫如果每次爬取都调用一次谷歌浏览器来实现操作,在性能上会有一定影响,而且连续开启十几个浏览器简直是内存噩梦, * 因此选用phantomJs来替换chromeDriver * PhantomJs在本地开发时候还好,如果要部署到服务器,就必须下载linux版本的PhantomJs,相比window操作繁琐 * @author zhuangj * @date 2017/11/14 */ public class TestPhantomJsDriver { public static PhantomJSDriver getPhantomJSDriver() throws Exception{ //设置必要参数 DesiredCapabilities dcaps = new DesiredCapabilities(); //ssl证书支持 dcaps.setCapability("acceptSslCerts", true); //截屏支持 dcaps.setCapability("takesScreenshot", false); //css搜索支持 dcaps.setCapability("cssSelectorsEnabled", true); //js支持 dcaps.setJavascriptEnabled(true); //驱动支持 dcaps.setCapability(PhantomJSDriverService.PHANTOMJS_EXECUTABLE_PATH_PROPERTY,"F:\\phantomjs\\phantomjs-2.1.1-windows\\bin\\phantomjs.exe"); PhantomJSDriver driver = new PhantomJSDriver(dcaps); return driver; } public static void main(String[] args) throws Exception { WebDriver driver=getPhantomJSDriver(); driver.get("https://www.886er.com/vod/17/11675-1.html"); WebElement webElement = driver.findElement(By.xpath("/html")); System.out.println("outerHTML======="+webElement.getAttribute("outerHTML")); System.out.println("url========="+driver.getCurrentUrl()); driver.quit(); } } |
以上demo感谢作者:https://www.cnblogs.com/null-qige/p/7844381.html
这样简单的渲染数据就基本是都可以爬取到了,可以直接整合到WebMagic里面去,当然WebMagic作者也整合了这一模块,我用的时候先是自己整了一下发现还是没有WebMagic作者的好用,接下来讲一下WebMagic里面这个模块。
首先我们需要下载源码:https://gitee.com/flashsword20/webmagic.git
因为这块业务太重所以源码作者没有把这一模块放到maven里面去,我们需要自己下载源码稍作修改
我们下载好源码后代开这个模块:
第一步先修改config.ini
第二步:
因为我是在windos下和linux都装了所以配置文件做了一个灵活的变动
这样当我们在linux还是windos下运行都可以不用来改源码了,只需要保证当前服务器位置是否有这文件就行
然后可以运行一下是否成功
成功之后把selenium这个模块打成jar包
得到这三个jar包之后把他们放到我们自己的maven仓库内,也可以不放,直接在project stru..内引用,但这样的话windos打war包丢linux服务器的时候会打不成功,提示文件不存在,所有我们还是放maven本地仓库吧
接下来,实现PageProcessor直接就可以用了,写法仿照源码模块内的HuabanProcessor类
main方法注意一下:
linux和windos下路径别弄错了,希望能帮助到你