Android进阶(十三)网络爬虫&json应用
刚开始接触网络爬虫,怎一个“菜”字了得!经过几次的折磨,对其原理以及其中用到的json技术有了大致的了解,故作一总结,供有同样迷惑的朋友参考学习。
自己爬取的网站内容为12306的余票查询模块。利用火狐浏览器为Web开发者置的Web控制台,可得到爬取网页的请求网址,如下图所示:
其中的请求网址即为我们需要爬取的网址。另外,可得知其请求协议采用的是Https协议,采用GET方式访问。爬取源代码如下所示:
public static String queryDate = "2015-04-19";
public static String from_station = "JNK";
public static String to_station = "BJP";
public static void main(String[] args) throws Exception {
HostnameVerifier hv = new HostnameVerifier() {
public boolean verify(String urlHostName, SSLSession session) {
System.out.println("Warning: URL Host: " + urlHostName
+ " vs. " + session.getPeerHost());
return true;
}
};
String url = "https://kyfw.12306.cn/otn/lcxxcx/query?purpose_codes=ADULT&queryDate="
+ queryDate
+ "&from_station="
+ from_station
+ "&to_station="
+ to_station;
ProtocolUrlValidator.trustAllHttpsCertificates();
HttpsURLConnection.setDefaultHostnameVerifier(hv);
String result = WebServiceUtil.invokeByHTTPGET(url, null);
Gson gson = new Gson();
Trains trains = gson.fromJson(result, Trains.class);
List<Item> items = trains.getData().getItems();
if (trains.getHttpstatus() != 200) {
trains.getMessages();
} else {
if (items != null && items.size() != 0)
for (Item item : items) {
System.out.println(item);
}
}
}
}
<span style="font-size:14px;">由于使用的协议为Https,故访问之前需要先进行证书的校验。其中蓝色代码块为我们需要访问的网址,涉及到的invokeByHTTPGET(url,null)代码如下所示:</span>
<span style="font-size:18px;">public class WebServiceUtil {
/**
* 通过SOAP1.1协议调用Web服务
*
* @param wsdl WSDL路径
* @param method 方法名
* @param namespace 命名空间
* @param headerParameters 头参数
* @param bodyParameters 体参数
* @param isBodyParametersNS 体参数是否有命名空间
* @return String
* @throws Exception
*/
public static String invokeBySoap11(String wsdl, String method,
String namespace, Map<String, String> headerParameters,
Map<String, String> bodyParameters, boolean isBodyParametersNS)
throws Exception {
StringBuffer soapOfResult = null;
// 去除 ?wsdl,获取方法列表
int length = wsdl.length();
wsdl = wsdl.substring(0, length - 5);
URL url = new URL(wsdl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setRequestProperty("Content-Type", "text/xml;charset=utf-8");
OutputStream out = conn.getOutputStream();
// 获取soap1.1版本消息
StringBuilder sb = new StringBuilder();
sb.append("<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"
xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" ");
sb.append("xmlns:ns0=\"" + namespace + "\"");
sb.append(">");
if (headerParameters != null) {
sb.append("<soap:Header>");
for (Entry<String, String> headerParameter : headerParameters
.entrySet()) {
sb.append("<ns0:");
sb.append(headerParameter.getKey());
sb.append(">");
sb.append(headerParameter.getValue());
sb.append("</ns0:");
sb.append(headerParameter.getKey());
sb.append(">");
}
sb.append("</soap:Header>");
}
sb.append("<soap:Body><ns0:");
sb.append(method);
sb.append(">");
// 输入参数
if (bodyParameters != null) {
for (Entry<String, String> inputParameter : bodyParameters
.entrySet()) {
if (isBodyParametersNS) {
sb.append("<ns0:");
sb.append(inputParameter.getKey());
sb.append(">");
sb.append(inputParameter.getValue());
sb.append("</ns0:");
sb.append(inputParameter.getKey());
sb.append(">");
} else {
sb.append("<");
sb.append(inputParameter.getKey());
sb.append(">");
sb.append(inputParameter.getValue());
sb.append("</");
sb.append(inputParameter.getKey());
sb.append(">");
}
}
}
sb.append("</ns0:");
sb.append(method);
sb.append("></soap:Body></soap:Envelope>");
//System.out.println(sb.toString());
out.write(sb.toString().getBytes());
int code = conn.getResponseCode();
if (code == 200) {
InputStream is = conn.getInputStream();
byte[] b = new byte[1024];
int len = 0;
soapOfResult = new StringBuffer();
while ((len = is.read(b)) != -1) {
String s = new String(b, 0, len, "UTF-8");
soapOfResult.append(s);
}
}
conn.disconnect();
return soapOfResult == null ? null : soapOfResult.toString();
}
/**
* 通过SOAP1.2协议调用Web服务
*
* @param wsdl
* @param method
* @param namespace
* @param headerParameters
* @param bodyParameters
* @param isBodyParametersNS
* @return
* @throws Exception
*/
public static String invokeBySoap12(String wsdl, String method,
String namespace, Map<String, String> headerParameters,
Map<String, String> bodyParameters, boolean isBodyParametersNS)
throws Exception {
StringBuffer soapOfResult = null;
// 去除 ?wsdl
int length = wsdl.length();
wsdl = wsdl.substring(0, length - 5);
URL url = new URL(wsdl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setRequestProperty("Content-Type", "text/xml;charset=utf-8");
OutputStream out = conn.getOutputStream();
// 获取soap1.1版本消息
StringBuilder sb = new StringBuilder();
sb.append("<soap12:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"
xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" soap12:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ");
sb.append("xmlns:ns0=\"" + namespace + "\"");
sb.append(">");
if (headerParameters != null) {
sb.append("<soap12:Header>");
for (Entry<String, String> headerParameter : headerParameters
.entrySet()) {
sb.append("<ns0:");
sb.append(headerParameter.getKey());
sb.append(">");
sb.append(headerParameter.getValue());
sb.append("</ns0:");
sb.append(headerParameter.getKey());
sb.append(">");
}
sb.append("</soap12:Header>");
}
sb.append("<soap12:Body><ns0:");
sb.append(method);
sb.append(">");
// 输入参数
if (bodyParameters != null) {
for (Entry<String, String> inputParameter : bodyParameters
.entrySet()) {
if (isBodyParametersNS) {
sb.append("<ns0:");
sb.append(inputParameter.getKey());
sb.append(">");
sb.append(inputParameter.getValue());
sb.append("</ns0:");
sb.append(inputParameter.getKey());
sb.append(">");
} else {
sb.append("<");
sb.append(inputParameter.getKey());
sb.append(">");
sb.append(inputParameter.getValue());
sb.append("</");
sb.append(inputParameter.getKey());
sb.append(">");
}
}
}
sb.append("</ns0:");
sb.append(method);
sb.append("></soap12:Body></soap12:Envelope>");
System.out.println(sb.toString());
out.write(sb.toString().getBytes());
int code = conn.getResponseCode();
if (code == 200) {
InputStream is = conn.getInputStream();
byte[] b = new byte[1024];
int len = 0;
soapOfResult = new StringBuffer();
while ((len = is.read(b)) != -1) {
String s = new String(b, 0, len, "UTF-8");
soapOfResult.append(s);
}
}
conn.disconnect();
return soapOfResult == null ? null : soapOfResult.toString();
}
/**
* 通过HTTP POST传参方式调用服务
*
* @param urlPath
* @param method
* @param namespace
* @param inputParameters
* @return
* @throws Exception
*/
public static String invokeByHTTPPOST(String urlPath, Map<String, String> inputParameters)
throws Exception {
StringBuffer resultStr = null;
URL url = new URL(urlPath);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
StringBuilder sb = new StringBuilder();
// 输入参数
if (inputParameters != null) {
for (Entry<String, String> inputParameter : inputParameters
.entrySet()) {
sb.append(inputParameter.getKey());
sb.append("=");
sb.append(inputParameter.getValue());
sb.append("&");
}
sb.deleteCharAt(sb.length() - 1);
}
System.out.println(sb.toString());
OutputStream out = conn.getOutputStream();
out.write(sb.toString().getBytes());
int code = conn.getResponseCode();
if (code == 200) {
InputStream is = conn.getInputStream();
byte[] b = new byte[1024];
int len = 0;
resultStr = new StringBuffer();
while ((len = is.read(b)) != -1) {
String s = new String(b, 0, len, "UTF-8");
resultStr.append(s);
}
}
conn.disconnect();
return resultStr == null ? null : resultStr.toString();
}
/**
* 通过HTTP GET传参方式调用服务
*
* @param urlPath url路径
* @param method 方法名
* @param namespace 命名空间
* @param inputParameters 输入参数
* @return String
* @throws Exception
*/
public static String invokeByHTTPGET(String urlPath, Map<String, String> inputParameters)
throws Exception {
StringBuilder sb = new StringBuilder();
sb.append(urlPath);
// GET参数
if (inputParameters != null) {
sb.append("?");
//entrySet()方法 返回此映射中包含的映射关系的 set 视图集合
//Map.Entry表示单个映射关系即一个key+value
for (Entry<String, String> inputParameter : inputParameters
.entrySet()) {
sb.append(inputParameter.getKey());
sb.append("=");
sb.append(inputParameter.getValue());
sb.append("&");
}
//作用:去除最后一个拼接的'&'字符
sb.deleteCharAt(sb.length() - 1);
}
System.out.println(sb.toString());
URL url = new URL(sb.toString());
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setDoOutput(true);
int code = conn.getResponseCode();
StringBuffer resultString = null;
if (code == 200) {
InputStream is = conn.getInputStream();
byte[] b = new byte[4096];
int len = 0;
resultString = new StringBuffer();
while ((len = is.read(b)) != -1) {
String s = new String(b, 0, len, "UTF-8");
//System.out.println(len+">>>>"+s);
resultString.append(s);
}
}
conn.disconnect();
return resultString == null ? null : resultString.toString();
}</span>
以上代码块涉及到的发送请求方式有通过SOAP1.1协议调用Web服务、通过SOAP1.2协议调用Web服务、
通过HTTP POST传参方式调用服务和通过HTTP GET传参方式调用服务。其具体的请求方式在源代码中以注释方式以详细给出,故此处不再赘述。
在爬取过程中,我们还需要用到json在线校验工具,网址为:点击打开链接。主要利用此工具完成的操作为:验证json格式的正确性,根据json串生成相应的POJO类。如下图所示:
json格式校验
生成POJO类
<span style="font-size:18px;">至此,网络爬虫的过程基本结束。此次实验的返回结果如下图所示:</span>
注:自己对GSon解析json还存在一定的误区。对于json串中的Key,其实是与相应类中的变量名一一对应的,否则,在解析式将会是null!例如,
以上的json串中存在key为data,则在创建POJO时,不可随意更变变量名,若将private List<Item> datas;改写为private List<Item> items;则会使变List<Item> items = trains.getData().getItems();返回null。若自己需要更改变量名的话,可以采用注解的方式解决,例如@SerializedName("datas")private List<Item> items;
Android进阶(十三)网络爬虫&json应用的更多相关文章
- python3.4学习笔记(十三) 网络爬虫实例代码,使用pyspider抓取多牛投资吧里面的文章信息,抓取政府网新闻内容
python3.4学习笔记(十三) 网络爬虫实例代码,使用pyspider抓取多牛投资吧里面的文章信息PySpider:一个国人编写的强大的网络爬虫系统并带有强大的WebUI,采用Python语言编写 ...
- 【Android进阶】Gson解析json字符串的简单应用
在客户端与服务器之间进行数据传输,一般采用两种数据格式,一种是xml,一种是json.这两种数据交换形式各有千秋,比如使用json数据格式,数据量会比较小,传输速度快,放便解析,而采用xml数据格式, ...
- python3.4学习笔记(十七) 网络爬虫使用Beautifulsoup4抓取内容
python3.4学习笔记(十七) 网络爬虫使用Beautifulsoup4抓取内容 Beautiful Soup 是用Python写的一个HTML/XML的解析器,它可以很好的处理不规范标记并生成剖 ...
- Android 自定义 ListView 显示网络上 JSON 格式歌曲列表
本文内容 环境 项目结构 演示自定义 ListView 显示网络上 JSON 歌曲列表 参考资料 本文最开始看的是一个国人翻译的文章,没有源代码可下载,根据文中提供的代码片段,自己新建的项目(比较可恶 ...
- Android Volley 库通过网络获取 JSON 数据
本文内容 什么是 Volley 库 Volley 能做什么 Volley 架构 环境 演示 Volley 库通过网络获取 JSON 数据 参考资料 Android 关于网络操作一般都会介绍 HttpC ...
- 我的Android进阶之旅------>解决Jackson等第三方转换Json的开发包在开启混淆后转换的实体类数据都是null的bug
1.错误描述 今天测试人员提了一个bug,说使用我们的app出现了闪退的bug,后来通过debug断点调试,发现我们的app转换服务器发送过来的json数据后,都是为null.而之前已经提测快一个月的 ...
- Android网络爬虫程序(基于Jsoup)
摘要:基于 Jsoup 实现一个 Android 的网络爬虫程序,抓取网页的内容并显示出来.写这个程序的主要目的是抓取海投网的宣讲会信息(公司.时间.地点)并在移动端显示,这样就可以随时随地的浏览在学 ...
- python网络爬虫进阶之HTTP原理,爬虫的基本原理,Cookies和代理介绍
目录 一.HTTP基本原理 (一)URI和URL (二)超文本 (三)HTTP和HTTPS (四)HTTP请求过程 (五)请求 1.请求方法 2.请求的网址 3.请求头 4.请求体 (六)响应 1.响 ...
- android基于MVP小说网络爬虫、宝贝社区APP、仿虎扑钉钉应用、滑动阴影效果等源码
Android精选源码 android宝贝社区app源码 android仿Tinder最漂亮的一个滑动效果 android仿滴滴打车开具发票页,ListView粘性Header Android基于MV ...
随机推荐
- Servlet技术 Cookie与Session
会话过程:用户打开浏览器,点击链接访问资源,最后到关闭浏览器的整个过程称之为会话. 会话使用:与服务器进行会话的过程中产生数据,数据被保存下来,服务器根据数据对客户进行辨别,做出个性化的响应. 介绍两 ...
- 4月18开始看《C++Primer Plus》
好久没有写博客了,之前也说过水平有限,也写不出什么技术博客,只能写些感悟. 过年之后,陆续做了2.3个项目,刚开始可能不太熟悉流程,怎么和页面传数据?最近一个项目1/2天就写完代码了,真的很简单,主要 ...
- .9-浅析express源码之请求处理流程(2)
上节漏了几个地方没有讲. 1.process_params 2.trim_prefix 3.done 分别是动态路由,深层路由与最终回调. 这节就只讲这三个地方,案例还是express-generat ...
- [HCNA]VLAN配置Access接口
实验目的 1.理解VLAN的应用场景 2.掌握VLAN的基本配置 3.掌握Access接口的配置方法 4.掌握Access接口加入相应VLAN的方法 实验仪器 eNSP 实验原理 如网络拓扑图所示 各 ...
- vs2017 +CUDA 9.0配置
环境: 1.Win7 64位 旗舰版 2.VS2017 3.CUDA 9.0 安装过程比较简单,直接运行在官网下载的CUDA安装包就可以了. 建议先安装VS,再安装CUDA.这样安装完之后会在VS里直 ...
- ubuntu批量更改文件权限
重装系统之后,把文件从windows分区拷到linux分区发现所有文件的权限全是777,在终端下看到所有文件的颜色都很刺眼,文件有很多,一个一个改不现实,所以写了一段python脚本批量更改文件权限. ...
- Python中enumerate用法详解
enumerate()是python的内置函数.适用于python2.x和python3.xenumerate在字典上是枚举.列举的意思enumerate参数为可遍历/可迭代的对象(如列表.字符串)e ...
- Node.js 虚拟机
稳定性: 3 - 稳定 可以通过以下方法访问该模块: var vm = require('vm'); JavaScript 可以立即编译立即执行,也可以编译,保存,之后再运行. vm.runInThi ...
- [CSDN_Markdown]使用LaTeX基本数学公式
简介 以前我很头疼在博文里写公式,一直期盼CSDN的博文编辑器能支持LaTeX 公式输入,今天终于可以使用这个功能了!此文主要讨论如何在CSDN的Markdown编辑器中写 LaTeX 公式! 使用L ...
- 在Ubuntu12.04上安装图形化配置与window共享的samba服务器
1.安装samba图形化配置界面 sudo apt-get install system-config-samba 2.启动图形化配置界面 3.添加用户,最好是要用adduser命令去添加 具体配置可 ...