java爬虫抓取动态网页( 2017年11月30日京东手机搜索页面的信息汇总)
优采云 发布时间: 2021-09-09 16:06java爬虫抓取动态网页(
2017年11月30日京东手机搜索页面的信息汇总)
Java爬虫在京东上实现抓取手机搜索页面。 HttpClient+Jsoup
更新时间:2017年11月30日09:42:41 作者:杂兵2号
下面小编给大家分享一个Java爬虫爬取京东上的手机搜索页面。 HttpCliient+Jsoup,有很好的参考价值,希望对大家有所帮助。跟着小编一起来看看
1、需求和配置
要求:抓取京东手机搜索页面信息,记录每款手机的名称、价格、评论数等,形成数据表,可用于实际分析。
使用Maven项目,log4j记录日志,日志只导出到控制台。
Maven依赖如下(pom.xml)
org.apache.httpcomponents
httpclient
4.5.3
org.jsoup
jsoup
1.11.2
log4j
log4j
1.2.17
log4j配置(log4j.properties),将INFO及以上级别信息输出到控制台,无需单独设置输出文件。
log4j.rootLogger=INFO, Console
#Console
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n
2、需求分析及代码
2.1 需求分析
第一步是建立客户端和服务器的连接,通过URL获取网页上的HTML内容。
第二步是解析HTML内容,获取需要的元素。
第三步是将HTML内容输出到本地文本文档,其他数据分析软件可以直接分析。
基于以上分析,建立了四个类,GetHTML(用于获取网站HTML)、ParseHTML(用于解析HTML)、WriteTo(用于输出文档)和Maincontrol(主控)。类说明。为了使代码尽可能简洁,所有异常都直接从方法中抛出,没有使用catch。
2.2Code
2.2.1GetHTML 类
该类收录两个方法:getH(String url)、urlControl(String baseurl, int page),分别用于获取网页的HTML和控制URL。由于本次抓取的网页内容只是京东某类商品的搜索结果,因此无需遍历页面上的所有网址。只需要观察翻页时URL的变化,就可以引入规则了。只暴露了 urlControl 方法,在类中设置了私有日志属性: private static Logger log = Logger.getLogger(getHTML.class);用于日志记录。
getH(String url),获取单个 URL 的 HTML 内容。
urlControl(String baseurl, int page),设置循环访问多个页面的数据。回顾一下元素,我们可以看出京东搜索页面的变化其实是奇数变化。
再次点击后查看URL的变化,可以发现实际变化的是page属性的值。拼接很容易得到下一个网页的地址。
%E6%89%8B%E6%9C%BA&enc=utf-8&qrst=1&rt=1&stop=1&vt=2&cid2=653&cid3=655&page=3&s=47&click=0
%E6%89%8B%E6%9C%BA&enc=utf-8&qrst=1&rt=1&stop=1&vt=2&cid2=653&cid3=655&page=5&s=111&click=0
%E6%89%8B%E6%9C%BA&enc=utf-8&qrst=1&rt=1&stop=1&vt=2&cid2=653&cid3=655&page=7&s=162&click=0
整体代码:
import java.io.IOException;
import org.apache.http.HttpEntity;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;
public class getHTML {
//建立日志
private static Logger log = Logger.getLogger(getHTML.class);
private static String getH(String url) throws ClientProtocolException, IOException {
//控制台输出日志,这样每条访问的URL都可以在控制台上看到访问情况
log.info("正在解析" + url);
/*
* 以下内容为HttpClient建立连接的一般用法
* 使用HttpClient建立客户端
* 使用get方法访问指定URL
* 获得应答
* */
CloseableHttpClient client = HttpClients.createDefault();
HttpGet get = new HttpGet(url);
CloseableHttpResponse response = client.execute(get);
/*
* 以下内容为将HTML内容转化为String
* 获得应答体
* 将应答体转为String格式,此处使用了EntityUtils中的toString方法,编码格式设置为"utf-8"
* 完成后关闭客户端与应答
* */
HttpEntity entity = response.getEntity();
String content;
if (entity != null) {
content = EntityUtils.toString(entity, "utf-8");
client.close();
response.close();
return content;
} else
return null;
}
public static void urlControl(String baseurl, int page) throws ClientProtocolException, IOException {
//设置当前页count
int count = 1;
//如果当前页小于想要爬取的页数则执行
while (count < page) {
//实际访问的URL为不变的URL值拼接上URL变化的值
String u = baseurl + (2 * count - 1) + "&click=0";
//此处调用ParseHTML类中的方法对URL中的HTML页面进行处理,后面详细介绍该类
String content = ParseHTML.parse(getH(u)).toString();
//此处调用WriteTo类中的方法对解析出来的内容写入到本地,后面详细介绍该类
WriteTo.writeto(content);
count++;
}
}
}
2.2.2ParseHTML 类
这一步需要通过review元素确定需要爬取的标签,然后通过Jsoup中的CSS选择器获取。
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
public class ParseHTML {
public static StringBuilder parse(String content)
{
//使用Jsoup中的parse方法对已经转换为String的HTML内容进行分析,返回值为Document类
Document doc = Jsoup.parse(content);
//使用选择器select对需要找的元素进行抓取,例如第一个select中选择的是ul标签中class属性等于gl-warp clearfix的内容
Elements ele = doc.select("ul[class = gl-warp clearfix]").select("li[class=gl-item]");
//设置一个容器,用于装各个属性
StringBuilder sb = new StringBuilder();
//通过上一个选择器可以获得整个页面中所有符合要求的元素,也即各款手机,下面则需要对每款手机进行遍历,获取其属性
for (Element e : ele) {
//此处对各个属性的获取参考了网上一篇爬取京东上内容的文章,应该有其他不同的写法
String id = e.attr("data-pid");
String mingzi = e.select("div[class = p-name p-name-type-2]").select("a").select("em").text();
String jiage = e.select("div[class=p-price]").select("strong").select("i").text();
String pinglun = e.select("div[class=p-commit]").select("strong").select("a").text();
//向容器中添加属性
sb.append(id+"\t");
sb.append(mingzi+"\t");
sb.append(jiage+"\t");
sb.append(pinglun+"\t");
sb.append("\r\n");
}
return sb;
}
}
2.2.3WriteTo 类
此类中的方法将解析的内容写入本地文件。只是简单的 IO。
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
public class WriteTo {
// 设置文件存放的位置
private static File f = new File("C:\\jingdong.txt");
public static void writeto(String content) throws IOException {
//使用续写的方式,以免覆盖前面写入的内容
BufferedWriter bw = new BufferedWriter(new FileWriter(f, true));
bw.append(content);
bw.flush();
bw.close();
}
}
2.2.4MainControl 类
主控程序,写基地址和要获取的页数。调用getHTML类中的urlControl方法抓取页面。
import java.io.IOException;
import org.apache.http.client.ClientProtocolException;
public class MainControl {
public static void main(String[] args) throws ClientProtocolException, IOException {
// TODO Auto-generated method stub
String baseurl = "https://search.jd.com/Search?keyword=%E6%89%8B%E6%9C%BA&enc="
+ "utf-8&qrst=1&rt=1&stop=1&vt=2&cid2=653&cid3=655&page=";
int page = 5;//设置爬取页数
getHTML.urlControl(baseurl, page);
}
}
3、爬取结果
抓取 20 页。
3.1 控制台输出
3.2文档输出
可以直接用Excel打开,分隔符是制表符。列是产品编号、名称、价格和评论数量。
4、小结