最近在做一个项目,通过扫描营业执照的二维码得到一条URL链接。一条链接跳转后会进入企业信息公示页面,需要通过这条链接获取需要的信息(公司名,法人,信用代码等等)。
在网上搜索了很多,也找到了很多方法,但是都不能爬取到。一般都是521 报错,没有跨域,网页使用的是JS动态加载,我们获取的只是静态信息等等。所以种种方法都是不可行的。
最后采用的方案是:WebClient 模拟一个浏览器客户端,设置JS动态加载开启(必须,主要应对那些JS,Ajax 动态加载的数据),然后使用HtmlPage 类接受该网页。使用Jsoup 进行清洗数据得到我们需要的内容。值得一提的是
Jsoup 的使用方法和JS 很相似。doc.getElementById("id") 和 doc.getElementsByTag(tagName) 一般使用这两个方法可以得到。我们在Google 浏览器中使用F12打开开发调试工具。使用定位功能,定位到我们所需数据的位置,查看标签的id ,这个id 就是我们使用Jsoup函数时使用的ID。这样就可以得到具体的值。具体Jsoup 用户可以百度搜索一下。
下面不说废话,直接上代码:
(1)环境
1)Jsoup 环境
<dependency>
<!-- jsoup HTML parser library @ http://jsoup.org/ -->
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.10.2</version>
</dependency>
2)WebClient环境
这个比较麻烦
我直接贴我自己项目中的Jar 的截图(如果需要,可以联系我)
(2)源码(这是一个获取企业信息的源码,其他都是类似的,webclient 模拟一样,就是清洗不同罢了)
public static List<String> analysisQyInfoForOld(String url){
final WebClient client = new WebClient();
client.getOptions().setJavaScriptEnabled(true);// 默认执行js
client.getOptions().setCssEnabled(false);
client.setAjaxController(new NicelyResynchronizingAjaxController());
client.getOptions().setThrowExceptionOnScriptError(false);
HtmlPage page = null;
try {
page = client.getPage(url);
} catch (FailingHttpStatusCodeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String pageXml = page.asXml(); //以xml的形式获取响应文本
List<String> lists = new ArrayList<String>();
/**jsoup解析文档*/
Document doc = Jsoup.parse(pageXml);
Element element1 = doc.getElementById("REG_NO"); //统一社会信用代码/注册号
Element element2 = doc.getElementById("CORP_NAME");//名称
Element element3 = doc.getElementById("ZJ_ECON_KIND");//类型
Element element4 = doc.getElementById("OPER_MAN_NAME");//经营者
Element element5 = doc.getElementById("FARE_PLACE");//经营场所
Element element7 = doc.getElementById("ADDR"); //住址
Element element6 = doc.getElementById("BELONG_ORG");//所属部门
lists.add(element1.text());
lists.add(element2.text());
lists.add(element3.text());
lists.add(element4.text());
if(element5 == null ) {
lists.add(element7.text());
}else {
lists.add(element5.text());
}
lists.add(element6.text());
return lists;
}
(3)这里分享一个错误
可能我们在运行的过程中,出现数据丢失,或者没有数据,获取不到我们想要的数据
这里可能主要是因为(Js 动态加载需要时间,而我们如果程序很快执行我们只是获取的是静态的HTML代码,而不是动态加载的数据)所以我们可以延迟一下,等待一下。
for (int i = 0; i < 2; i++) {
if (!page.getByXPath("//div[@class='c-gap-top c-recommend']").isEmpty()) {
break;
}
synchronized (page) {
page.wait(10);
}
}
放在HtmlPage page = client.getPage(url); 下面即可。
这样我们完成了爬取,这个可以做爬虫,为我们效力