使用java做网络爬虫中获取网页数据的问题

qwe_abc_123 2012-01-16 02:20:15
最近在做一个搜索项目,所以刚开始学习网络爬虫的内容,使用java开发的

在爬去哪儿的机票信息时,发现页面显示的机票信息并不在页面源代码中出现,
导致即使下载了该页面也无法获得页面内的机票信息

所以在这里想问一下对于这种动态产生结果的网站,要如何处理才能用网络爬虫获得那部分的数据
可以的话,也请大家告知这种动态产生结果是如何是实现的
求高手指教,在此先谢过大家

ps:由于第一次在此发帖,不知是否应该发在这个版区,若有不妥,请版主指出,再做修改
...全文
4381 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
qingralf 2012-01-18
  • 打赏
  • 举报
回复

Map<String,String> param = new HashMap<String,String>();
param.put("http://www.travelco.com/searchDepartureAirport", "哈尔滨");//出发
param.put("http://www.travelco.com/searchArrivalAirport", "北京");//到站
param.put("http://www.travelco.com/searchDepartureTime", "2012-01-29");//日期
param.put("searchType", "OneWayFlight");

Document doc = Jsoup.connect("http://flight.qunar.com/twell/longwell").data(param).get();
String result = doc.text();
result = result.substring(1, result.length()-1);
System.out.println(result);
Gson gson = new Gson();
HashMap map = gson.fromJson(result, HashMap.class);
Map priceInfo = (Map)((Map)map.get("oneway_data")).get("priceInfo");
for(Object tmp:priceInfo.keySet()){
System.out.println(tmp + " 最低票价: "+((Map)priceInfo.get(tmp)).get("lowpr"));
}


需要jsoup,gson的支持.解析的时候看着很不优雅...
qwe_abc_123 2012-01-18
  • 打赏
  • 举报
回复
好的,谢谢你的帮忙
  • 打赏
  • 举报
回复
sleep就sleep吧,如果觉得速度慢可以试试加进程. 线程我试过不明显, 加进程应该可以解决. 用不同的客户端去跑,每个跑不同的链接,汇总数据push到你统一的数据集中.
  • 打赏
  • 举报
回复
那应该是页面加载完了,但是页面中的ajax二次请求还没返回,之前还真没碰到
qwe_abc_123 2012-01-18
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 zdsdiablo 的回复:]

webClient.getPage(...);
这行执行完就加载完了,处理逻辑直接写下面就可以了
[/Quote]
但是我用这段代码测试的

WebClient w = new WebClient();
w.setJavaScriptEnabled(true);
HtmlPage page = (HtmlPage) w.getPage("http://flight.qunar.com/site/oneway_list.htm?searchDepartureAirport=%E5%93%88%E5%B0%94%E6%BB%A8&searchArrivalAirport=%E5%8C%97%E4%BA%AC&searchDepartureTime=2012-01-29&searchArrivalTime=2012-01-29&nextNDays=0&startSearch=true&from=fi_ont_search");
List<DomNode> nodes = (List<DomNode>) page.getByXPath("/html/body/div[3]/div[4]/div/div[5]");
//Thread.sleep(10000);
for (DomNode node : nodes) {
System.out.println(node.asText());
}


如果没有sleep结果如下:
最低报价
请稍等,您查询的结果正在实时搜索中...
想去哪儿就去哪儿
如果您无法快速看到搜索结果,请同时按下键盘上的Ctrl+F5强制刷新页面。
更多问题,请点击此处了解<<

但如果有sleep就会有列表信息
  • 打赏
  • 举报
回复
webClient.getPage(...);
这行执行完就加载完了,处理逻辑直接写下面就可以了
qwe_abc_123 2012-01-18
  • 打赏
  • 举报
回复
难道是使用waitForBackgroundJavaScript这个方法吗
qwe_abc_123 2012-01-18
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 zdsdiablo 的回复:]

我记得htmlunit本身不是异步的,而且只能对单独页面读取,换页面要重新读,麻烦点.放在线程里能稍微提高那么一点速度,效果不明显.据htmlunit开发团队的人说,主要速度是卡在网速上了,反正我不信,不信也没用.对于这个加载时间,应该可以等加载完主动触发,而不是用sleep等待.
当时用htmlunit写主要的好处在于xpath,一般的页面读取都是不解析的,后果是找内容只能用正则,万一加入混……
[/Quote]

所以我想问有办法知道他加载完吗?
qwe_abc_123 2012-01-18
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 qingralf 的回复:]

确定你的gson版本是比较新的么?这边运行过才发的.
或者把代码贴上来.我这边跑一下.
[/Quote]

gson我是在http://code.google.com/p/google-gson/downloads/list这里下的
我没有做修改代码
  • 打赏
  • 举报
回复
我记得htmlunit本身不是异步的,而且只能对单独页面读取,换页面要重新读,麻烦点.放在线程里能稍微提高那么一点速度,效果不明显.据htmlunit开发团队的人说,主要速度是卡在网速上了,反正我不信,不信也没用.对于这个加载时间,应该可以等加载完主动触发,而不是用sleep等待.
当时用htmlunit写主要的好处在于xpath,一般的页面读取都是不解析的,后果是找内容只能用正则,万一加入混淆正则就很难写了.
祝好运吧
qwe_abc_123 2012-01-18
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 zdsdiablo 的回复:]

是,那个网站早关了, 看程序思路即可. Junithtml是一个无界面的浏览器,可以获取互联网上的网页信息,效率稍低,读取到内容后可以按照xpath解析, 如果是动态插入的内容,只要开放javascript就可以读到.
xpath就和jquery,css的选择器差不多,能理解例子的话可以直接用junithtml来写.

[/Quote]

刚才将javascript开放后,将线程sleep一段时间确实可以得到动态插入的内容,谢谢高手指教
但是还有个问题,我怎样可以知道它已经动态加载完了,如果都用同个时间去sleep,对于航班量少的不就挺不划算吗?
qingralf 2012-01-18
  • 打赏
  • 举报
回复
确定你的gson版本是比较新的么?这边运行过才发的.
或者把代码贴上来.我这边跑一下.
qwe_abc_123 2012-01-18
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 qingralf 的回复:]

Java code

Map<String,String> param = new HashMap<String,String>();
param.put("http://www.travelco.com/searchDepartureAirport", "哈尔滨");//出发
param.put("http://www.travelco.com/searchA……
[/Quote]

试着运行ls的代码,返回的result成功,但gson调用fromjson的方法出现异常
具体异常如下:
Exception in thread "main" java.lang.NullPointerException
at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.read(MapTypeAdapterFactory.java:186)
at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.read(MapTypeAdapterFactory.java:146)
at com.google.gson.Gson.fromJson(Gson.java:755)
at com.google.gson.Gson.fromJson(Gson.java:721)
at com.google.gson.Gson.fromJson(Gson.java:670)
at com.google.gson.Gson.fromJson(Gson.java:642)
at WebClientTest.main(WebClientTest.java:33)

请问这是什么问题呢
我百度了一下,不知是不是下面链接中4楼说的问题
http://topic.csdn.net/u/20110217/11/910681be-13e3-4b7d-93b0-0b327dbbd3f3.html
  • 打赏
  • 举报
回复
刚拼错了,是htmlunit,单页的测试可以谷歌一下还是很多的. 发的grabage第二版应该不用改代码,配xml即可,如果看着太辛苦,可以先找几个htmlunit基础内容来看. 思路是一样的,写grabage就是把一些抓取过程做成xml配置了.如果是搜索引擎,只要重新封装这块就可以完成. 不过htmlunit效率不高, 看内容就是做参考吧.商用的搜索引擎这种速度肯定是不行的.

[Quote=引用 3 楼 qwe_abc_123 的回复:]

之后我单独使用webclient来获取一个页面(方法与grabage的相似),发现还是之前遇到的问题
也就是只能得到“正在搜索中请稍后”的信息,得不到真正在浏览器显示的航班信息

跪求帮助
[/Quote]
  • 打赏
  • 举报
回复
是,那个网站早关了, 看程序思路即可. Junithtml是一个无界面的浏览器,可以获取互联网上的网页信息,效率稍低,读取到内容后可以按照xpath解析, 如果是动态插入的内容,只要开放javascript就可以读到.
xpath就和jquery,css的选择器差不多,能理解例子的话可以直接用junithtml来写.

[Quote=引用 2 楼 qwe_abc_123 的回复:]

那个刚刚试了一下那个项目,运行得出下面的结果:
[config]start:1326806707117
[config]complete:1326806707158
[grabage]start:1326806707158
>>>LINK>>>http://portal.czol.info/news/money
java.net.UnknownHostException: portal……
[/Quote]
qwe_abc_123 2012-01-17
  • 打赏
  • 举报
回复
之后我单独使用webclient来获取一个页面(方法与grabage的相似),发现还是之前遇到的问题
也就是只能得到“正在搜索中请稍后”的信息,得不到真正在浏览器显示的航班信息

跪求帮助
qwe_abc_123 2012-01-17
  • 打赏
  • 举报
回复
那个刚刚试了一下那个项目,运行得出下面的结果:
[config]start:1326806707117
[config]complete:1326806707158
[grabage]start:1326806707158
>>>LINK>>>http://portal.czol.info/news/money
java.net.UnknownHostException: portal.czol.info
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at org.apache.commons.httpclient.protocol.DefaultProtocolSocketFactory.createSocket(DefaultProtocolSocketFactory.java:80)
at org.apache.commons.httpclient.protocol.DefaultProtocolSocketFactory.createSocket(DefaultProtocolSocketFactory.java:122)
at org.apache.commons.httpclient.HttpConnection.open(HttpConnection.java:707)
at org.apache.commons.httpclient.MultiThreadedHttpConnectionManager$HttpConnectionAdapter.open(MultiThreadedHttpConnectionManager.java:1361)
at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:387)
at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171)
at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397)
at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:346)
at com.gargoylesoftware.htmlunit.HttpWebConnection.getResponse(HttpWebConnection.java:101)
at com.gargoylesoftware.htmlunit.WebClient.loadWebResponseFromWebConnection(WebClient.java:1407)
at com.gargoylesoftware.htmlunit.WebClient.loadWebResponse(WebClient.java:1340)
at com.gargoylesoftware.htmlunit.WebClient.getPage(WebClient.java:299)
at com.gargoylesoftware.htmlunit.WebClient.getPage(WebClient.java:360)
at com.gargoylesoftware.htmlunit.WebClient.getPage(WebClient.java:345)
at info.czol.grabage.read.GrabageReader.reloadPageConfig(GrabageReader.java:132)
at info.czol.grabage.read.GrabageReader.startReadPage(GrabageReader.java:111)
at info.czol.grabage.ReadCenter.startRead(ReadCenter.java:20)
at info.czol.grabage.ReadCenter.main(ReadCenter.java:29)
[grabage]complete:1326806707203

这些异常不知是否是http://portal.czol.info/news/money这个网页无法连接的原因

然后我单独使用了read包里的测试类TestReadPageXpath,直接将
xconfig.setXlink("//table[@class='box']//a[@href]");
xconfig.setLink("http://portal.czol.info/news/money");
xconfig.setForward("http://portal.czol.info");
修改成
xconfig.setXlink("/html/body//h1");
xconfig.setLink("http://money.163.com");
xconfig.setForward("http://money.163.com");
还是抛出异常
好像是webclient在调用getpage()出错了
所以我想问一下这样测试是否有问题
  • 打赏
  • 举报
回复
你可以参考一下http://code.google.com/p/grabage/

50,531

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧