
httpclient 抓取网页
httpclient 抓取网页( 4)commons-io工具,获取页面或Json5))
网站优化 • 优采云 发表了文章 • 0 个评论 • 60 次浏览 • 2021-10-10 03:22
4)commons-io工具,获取页面或Json5))
4)commons-io 工具,获取页面或者 Json
5) Jsoup工具(一般用于html字段解析),获取页面,非Json返回格式]
----------------------------------------------- ---------------------------------
完整代码:
package com.yeezhao.common.http; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpMethod; import org.apache.commons.httpclient.methods.GetMethod; import org.apache.commons.io.IOUtils; import org.jsoup.Jsoup; /** * http工具对比 * * @author Administrator -> junhong * * 2016年12月27日 */ public class HttpFetchUtil { /** * 获取访问的状态码 * @param request * @return * @throws Exception */ public static int getResponseCode(String request) throws Exception { URL url = new URL(request); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); return conn.getResponseCode(); } /** * 1)JDK自带HTTP连接,获取页面或Json * @param request * @param charset * @return * @throws Exception */ public static String JDKFetch(String request, String charset) throws Exception { URL url = new URL(request); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); //模拟浏览器参数 conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36" + " (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36"); if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) { InputStream input = conn.getInputStream(); StringBuffer sb = new StringBuffer(); BufferedReader reader = new BufferedReader(new InputStreamReader(input, charset)); String s; while ((s = reader.readLine()) != null) { sb.append(s + "\n"); } input.close(); conn.disconnect(); return sb.toString(); } return ""; } /** * 2) JDK自带URL连接,获取页面或Json * @param request * @param charset * @return * @throws Exception */ public static String URLFetch(String request, String charset) throws Exception { URL url = new URL(request); return IOUtils.toString(url.openStream()); } /** * 3)HttpClient Get工具,获取页面或Json * @param url * @param charset * @return * @throws Exception */ public static String httpClientFetch(String url, String charset) throws Exception { // GET HttpClient httpClient = new HttpClient(); httpClient.getParams().setContentCharset(charset); HttpMethod method = new GetMethod(url); httpClient.executeMethod(method); return method.getResponseBodyAsString(); } /** * 4)commons-io工具,获取页面或Json * @param url * @param charset * @return * @throws Exception */ public static String commonsIOFetch(String url, String charset) throws Exception { return IOUtils.toString(new URL(url), charset); } /** * 5) Jsoup工具(通常用于html字段解析),获取页面,非Json返回格式 * @param url * @return * @throws Exception */ public static String jsoupFetch(String url) throws Exception { return Jsoup.parse(new URL(url), 2 * 1000).html(); } }
测试代码:
package com.yeezhao.common.http; import org.junit.After; import org.junit.Before; import org.junit.Test; /** * 测试类 * 3个测试链接: * 1)百科网页 * 2)浏览器模拟获取接口数据 * 3)获取普通接口数据 * @author Administrator -> junhong * * 2016年12月27日 */ public class HttpFetchUtilTest { String seeds[] = {"http://baike.baidu.com/view/1.htm","http://m.ximalaya.com/tracks/26096131.json","http://remyapi.yeezhao.com/api ... ot%3B}; final static String DEFAULT_CHARSET = "UTF-8"; @Before public void setUp() throws Exception { } @After public void tearDown() throws Exception { System.out.println("--- down ---"); } @Test public void testGetResponseCode() throws Exception{ for(String seed:seeds){ int responseCode = HttpFetchUtil.getResponseCode(seed); System.out.println("ret="+responseCode); } } @Test public void testJDKFetch() throws Exception{ for(String seed:seeds){ String ret = HttpFetchUtil.JDKFetch(seed, DEFAULT_CHARSET); System.out.println("ret="+ret); } } @Test public void testURLFetch() throws Exception{ for(String seed:seeds){ String ret = HttpFetchUtil.URLFetch(seed, DEFAULT_CHARSET); System.out.println("ret="+ret); } } @Test public void testHttpClientFetch()throws Exception { for(String seed:seeds){ String ret = HttpFetchUtil.httpClientFetch(seed, DEFAULT_CHARSET); System.out.println("ret="+ret); } } @Test public void testCommonsIOFetch()throws Exception { for(String seed:seeds){ String ret = HttpFetchUtil.commonsIOFetch(seed, DEFAULT_CHARSET); System.out.println("ret="+ret); } } @Test public void testJsoupFetch() throws Exception{ for(String seed:seeds){ String ret = HttpFetchUtil.jsoupFetch(seed); System.out.println("ret="+ret); } } }
附件:相关jar依赖
... org.jsoupjsoup1.7.3 commons-httpclientcommons-httpclient3.1 commons-iocommons-io2.4 ...
以上是Java中HTTP数据捕获的各种方式的详细讲解。更多详情请关注其他相关html中文网站文章! 查看全部
httpclient 抓取网页(
4)commons-io工具,获取页面或Json5))

4)commons-io 工具,获取页面或者 Json

5) Jsoup工具(一般用于html字段解析),获取页面,非Json返回格式]

----------------------------------------------- ---------------------------------
完整代码:
package com.yeezhao.common.http; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpMethod; import org.apache.commons.httpclient.methods.GetMethod; import org.apache.commons.io.IOUtils; import org.jsoup.Jsoup; /** * http工具对比 * * @author Administrator -> junhong * * 2016年12月27日 */ public class HttpFetchUtil { /** * 获取访问的状态码 * @param request * @return * @throws Exception */ public static int getResponseCode(String request) throws Exception { URL url = new URL(request); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); return conn.getResponseCode(); } /** * 1)JDK自带HTTP连接,获取页面或Json * @param request * @param charset * @return * @throws Exception */ public static String JDKFetch(String request, String charset) throws Exception { URL url = new URL(request); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); //模拟浏览器参数 conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36" + " (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36"); if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) { InputStream input = conn.getInputStream(); StringBuffer sb = new StringBuffer(); BufferedReader reader = new BufferedReader(new InputStreamReader(input, charset)); String s; while ((s = reader.readLine()) != null) { sb.append(s + "\n"); } input.close(); conn.disconnect(); return sb.toString(); } return ""; } /** * 2) JDK自带URL连接,获取页面或Json * @param request * @param charset * @return * @throws Exception */ public static String URLFetch(String request, String charset) throws Exception { URL url = new URL(request); return IOUtils.toString(url.openStream()); } /** * 3)HttpClient Get工具,获取页面或Json * @param url * @param charset * @return * @throws Exception */ public static String httpClientFetch(String url, String charset) throws Exception { // GET HttpClient httpClient = new HttpClient(); httpClient.getParams().setContentCharset(charset); HttpMethod method = new GetMethod(url); httpClient.executeMethod(method); return method.getResponseBodyAsString(); } /** * 4)commons-io工具,获取页面或Json * @param url * @param charset * @return * @throws Exception */ public static String commonsIOFetch(String url, String charset) throws Exception { return IOUtils.toString(new URL(url), charset); } /** * 5) Jsoup工具(通常用于html字段解析),获取页面,非Json返回格式 * @param url * @return * @throws Exception */ public static String jsoupFetch(String url) throws Exception { return Jsoup.parse(new URL(url), 2 * 1000).html(); } }
测试代码:
package com.yeezhao.common.http; import org.junit.After; import org.junit.Before; import org.junit.Test; /** * 测试类 * 3个测试链接: * 1)百科网页 * 2)浏览器模拟获取接口数据 * 3)获取普通接口数据 * @author Administrator -> junhong * * 2016年12月27日 */ public class HttpFetchUtilTest { String seeds[] = {"http://baike.baidu.com/view/1.htm","http://m.ximalaya.com/tracks/26096131.json","http://remyapi.yeezhao.com/api ... ot%3B}; final static String DEFAULT_CHARSET = "UTF-8"; @Before public void setUp() throws Exception { } @After public void tearDown() throws Exception { System.out.println("--- down ---"); } @Test public void testGetResponseCode() throws Exception{ for(String seed:seeds){ int responseCode = HttpFetchUtil.getResponseCode(seed); System.out.println("ret="+responseCode); } } @Test public void testJDKFetch() throws Exception{ for(String seed:seeds){ String ret = HttpFetchUtil.JDKFetch(seed, DEFAULT_CHARSET); System.out.println("ret="+ret); } } @Test public void testURLFetch() throws Exception{ for(String seed:seeds){ String ret = HttpFetchUtil.URLFetch(seed, DEFAULT_CHARSET); System.out.println("ret="+ret); } } @Test public void testHttpClientFetch()throws Exception { for(String seed:seeds){ String ret = HttpFetchUtil.httpClientFetch(seed, DEFAULT_CHARSET); System.out.println("ret="+ret); } } @Test public void testCommonsIOFetch()throws Exception { for(String seed:seeds){ String ret = HttpFetchUtil.commonsIOFetch(seed, DEFAULT_CHARSET); System.out.println("ret="+ret); } } @Test public void testJsoupFetch() throws Exception{ for(String seed:seeds){ String ret = HttpFetchUtil.jsoupFetch(seed); System.out.println("ret="+ret); } } }
附件:相关jar依赖
... org.jsoupjsoup1.7.3 commons-httpclientcommons-httpclient3.1 commons-iocommons-io2.4 ...
以上是Java中HTTP数据捕获的各种方式的详细讲解。更多详情请关注其他相关html中文网站文章!
httpclient 抓取网页(如何用httpclient+jsoup实现抓取网页分享(图))
网站优化 • 优采云 发表了文章 • 0 个评论 • 53 次浏览 • 2021-09-28 21:13
和之前的博客一样,我在学习使用httpclient实现网络爬虫的时候,在网上搜索了很多资料,但是httpclient版本是3.1或4.3的之前版本。我使用我自己了解的 httpclient4.5。今天把自己写的httpclient+jsoup的网页爬取分享给大家。
httpclient+jsoup 获取网页非常简单。首先通过httpclient的get方法获取一个网页的所有内容(有不懂的可以看我上一篇get方法的文章),然后通过jsoup获取一个网页的所有内容。解析内容,获取该网页中的所有链接,然后通过get方法获取这些链接中网页的内容,这样我们就可以获取到一个网页下所有链接的网页内容。例如,如果我们得到一个网页,它下面有 50 个链接,我们可以得到 50 个网页。下面是代码,让我们感受一下
获取网址
public class GetUrl {
public static List getUrl(String ur) {
//创建默认的httpClient实例
CloseableHttpClient client = HttpClients.createDefault();
//创建list存放已读取过的页面
List urllist = new ArrayList();
//创建get
HttpGet get=new HttpGet(ur);
//设置连接超时
Builder custom = RequestConfig.custom();
RequestConfig config = custom.setConnectTimeout(5000).setConnectionRequestTimeout(1000).setSocketTimeout(5000).build();
get.setConfig(config);
//设置消息头部
get.setHeader("Accept", "Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
get.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; rv:6.0.2) Gecko/20100101 Firefox/6.0.2");
try {
//执行get请求
CloseableHttpResponse response = client.execute(get);
//获取响应实体
HttpEntity entity = response.getEntity();
//将响应实体转为String类型
String html = EntityUtils.toString(entity);
//通过jsoup将String转为jsoup可处理的文档类型
Document doc = Jsoup.parse(html);
//找到该页面中所有的a标签
Elements links = doc.getElementsByTag("a");
int i=1;
for (Element element : links) {
//获取到a标签中href属性的内容
String url = element.attr("href");
//对href内容进行判断 来判断该内容是否是url
if(url.startsWith("http://blog.csdn.net/") && !urllist.contains(url)){
GetPage.getPage(url);
System.out.println(url);
urllist.add(url);
i++;
}
}
response.close();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return urllist;
}
}
根据获取到的url生成页面
最后,测试类
public class Test {
public static void main(String[] args) {
List list = GetUrl.getUrl("http://blog.csdn.net/");
System.out.println("所写链接内的所有内容");
int i=1;
for (String url : list) {
GetUrl.getUrl(url);
System.out.println("第"+i+"条链接内容");
i++;
}
}
}
以上就是如何使用httpclient+jsoup爬取网页。我希望它会对大家有所帮助。 查看全部
httpclient 抓取网页(如何用httpclient+jsoup实现抓取网页分享(图))
和之前的博客一样,我在学习使用httpclient实现网络爬虫的时候,在网上搜索了很多资料,但是httpclient版本是3.1或4.3的之前版本。我使用我自己了解的 httpclient4.5。今天把自己写的httpclient+jsoup的网页爬取分享给大家。
httpclient+jsoup 获取网页非常简单。首先通过httpclient的get方法获取一个网页的所有内容(有不懂的可以看我上一篇get方法的文章),然后通过jsoup获取一个网页的所有内容。解析内容,获取该网页中的所有链接,然后通过get方法获取这些链接中网页的内容,这样我们就可以获取到一个网页下所有链接的网页内容。例如,如果我们得到一个网页,它下面有 50 个链接,我们可以得到 50 个网页。下面是代码,让我们感受一下
获取网址
public class GetUrl {
public static List getUrl(String ur) {
//创建默认的httpClient实例
CloseableHttpClient client = HttpClients.createDefault();
//创建list存放已读取过的页面
List urllist = new ArrayList();
//创建get
HttpGet get=new HttpGet(ur);
//设置连接超时
Builder custom = RequestConfig.custom();
RequestConfig config = custom.setConnectTimeout(5000).setConnectionRequestTimeout(1000).setSocketTimeout(5000).build();
get.setConfig(config);
//设置消息头部
get.setHeader("Accept", "Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
get.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; rv:6.0.2) Gecko/20100101 Firefox/6.0.2");
try {
//执行get请求
CloseableHttpResponse response = client.execute(get);
//获取响应实体
HttpEntity entity = response.getEntity();
//将响应实体转为String类型
String html = EntityUtils.toString(entity);
//通过jsoup将String转为jsoup可处理的文档类型
Document doc = Jsoup.parse(html);
//找到该页面中所有的a标签
Elements links = doc.getElementsByTag("a");
int i=1;
for (Element element : links) {
//获取到a标签中href属性的内容
String url = element.attr("href");
//对href内容进行判断 来判断该内容是否是url
if(url.startsWith("http://blog.csdn.net/") && !urllist.contains(url)){
GetPage.getPage(url);
System.out.println(url);
urllist.add(url);
i++;
}
}
response.close();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return urllist;
}
}
根据获取到的url生成页面
最后,测试类
public class Test {
public static void main(String[] args) {
List list = GetUrl.getUrl("http://blog.csdn.net/");
System.out.println("所写链接内的所有内容");
int i=1;
for (String url : list) {
GetUrl.getUrl(url);
System.out.println("第"+i+"条链接内容");
i++;
}
}
}
以上就是如何使用httpclient+jsoup爬取网页。我希望它会对大家有所帮助。
httpclient 抓取网页(某电商商品详细信息的整体架构布局(图)、业务需求 )
网站优化 • 优采云 发表了文章 • 0 个评论 • 71 次浏览 • 2021-09-26 14:15
)
HtmlCleaner&xPath:网页分析软件,解析出需要的相关信息。
MySQL数据库:用于存储爬取到的产品的详细信息。
ZooKeeper:分布式协调工具,用于监控后期各个爬虫的运行状态。
三、业务需求
获取电子商务产品的详细信息,需要的相关字段有:产品ID、产品名称、产品价格和产品详细信息。
四、 整体结构布局
第一个是我们的核心部件爬虫程序。爬虫过程是:从Redis数据仓库中取出URL,使用HttpClient进行下载,下载的页面内容,我们使用HtmlCleaner和xPath进行页面分析,此时我们解析的页面可能是产品列表页面,或者它可能是产品的详细页面。如果是产品列表页面,则需要在页面中解析出产品详情页面的URL,放入Redis数据仓库进行后期分析;如果是产品详细信息页面,请将其存储在我们的 MySQL 数据中。具体架构图如下:
核心程序爬虫写好后,为了加快页面爬取效率,我们需要对爬虫进行改进:一是爬虫程序多线程化;二是将爬虫部署到多台服务器上,进一步加快爬虫的爬取效率。在实际生产环境中,由于刀片服务器稳定性较差,可能会出现一些问题,例如:爬虫进程挂掉。这些问题可能经常发生,所以我们需要对其进行监控。一旦发现爬虫进程挂掉,立即启动脚本重启爬虫进程,保证我们整个爬虫核心的持续运行。这是我们的分布式协调服务 ZooKeeper 的使用。我们可以再写一个进程监控程序,实时监控爬虫的运行状态。原理是:爬虫启动时,在ZooKeeper服务中注册自己的临时目录,监控程序使用ZooKeeper对爬虫注册的临时目录进行监控。ZooKeeper的本质——如果注册临时目录的程序挂了,过一会临时目录就会消失。利用这种性质,我们的监控程序监控爬虫注册的临时目录。一旦发现临时目录消失,服务器就会发生变化。其上的爬虫进程已经暂停,所以我们需要启动脚本来重启爬虫进程。然后我们将捕获的产品的详细信息存储在我们的分布式 MySQL 数据库中。以下是整个爬虫项目的架构图:它在ZooKeeper服务中注册了自己的临时目录,监控程序使用ZooKeeper来监控爬虫注册的临时目录。ZooKeeper的本质——如果注册临时目录的程序挂了,过一会临时目录就会消失。利用这种性质,我们的监控程序监控爬虫注册的临时目录。一旦发现临时目录消失,服务器就会发生变化。其上的爬虫进程已经暂停,所以我们需要启动脚本来重启爬虫进程。然后我们将捕获的产品的详细信息存储在我们的分布式 MySQL 数据库中。以下是整个爬虫项目的架构图:它在ZooKeeper服务中注册了自己的临时目录,监控程序使用ZooKeeper来监控爬虫注册的临时目录。ZooKeeper的本质——如果注册临时目录的程序挂了,过一会临时目录就会消失。利用这种性质,我们的监控程序监控爬虫注册的临时目录。一旦发现临时目录消失,服务器就会发生变化。其上的爬虫进程已经暂停,所以我们需要启动脚本来重启爬虫进程。然后我们将捕获的产品的详细信息存储在我们的分布式 MySQL 数据库中。以下是整个爬虫项目的架构图:监控程序使用ZooKeeper监控爬虫注册的临时目录。ZooKeeper的本质——如果注册临时目录的程序挂了,过一会临时目录就会消失。利用这种性质,我们的监控程序监控爬虫注册的临时目录。一旦发现临时目录消失,服务器就会发生变化。其上的爬虫进程已经暂停,所以我们需要启动脚本来重启爬虫进程。然后我们将捕获的产品的详细信息存储在我们的分布式 MySQL 数据库中。以下是整个爬虫项目的架构图:监控程序使用ZooKeeper监控爬虫注册的临时目录。ZooKeeper的本质——如果注册临时目录的程序挂了,过一会临时目录就会消失。利用这种性质,我们的监控程序监控爬虫注册的临时目录。一旦发现临时目录消失,服务器就会发生变化。其上的爬虫进程已经暂停,所以我们需要启动脚本来重启爬虫进程。然后我们将捕获的产品的详细信息存储在我们的分布式 MySQL 数据库中。以下是整个爬虫项目的架构图:ZooKeeper的本质——如果注册临时目录的程序挂了,过一会临时目录就会消失。利用这种性质,我们的监控程序监控爬虫注册的临时目录。一旦发现临时目录消失,服务器就会发生变化。其上的爬虫进程已经暂停,所以我们需要启动脚本来重启爬虫进程。然后我们将捕获的产品的详细信息存储在我们的分布式 MySQL 数据库中。以下是整个爬虫项目的架构图:ZooKeeper的本质——如果注册临时目录的程序挂了,过一会临时目录就会消失。利用这种性质,我们的监控程序监控爬虫注册的临时目录。一旦发现临时目录消失,服务器就会发生变化。其上的爬虫进程已经暂停,所以我们需要启动脚本来重启爬虫进程。然后我们将捕获的产品的详细信息存储在我们的分布式 MySQL 数据库中。以下是整个爬虫项目的架构图:服务器将被更改。其上的爬虫进程已经暂停,所以我们需要启动脚本来重启爬虫进程。然后我们将捕获的产品的详细信息存储在我们的分布式 MySQL 数据库中。以下是整个爬虫项目的架构图:服务器将被更改。其上的爬虫进程已经暂停,所以我们需要启动脚本来重启爬虫进程。然后我们将捕获的产品的详细信息存储在我们的分布式 MySQL 数据库中。以下是整个爬虫项目的架构图:
接下来,我们将重点分析爬虫架构的各个部分。
五、Redis 数据库-临时存储要爬取的 URL。
Redis 数据库是一个基于内存的 Key-Value 非关系型数据库。由于其极快的读写速度,受到了人们的热烈追捧(读写速度约为每秒10W)。Redis 数据库用于临时数据存储的选择就是基于此。为了让我们的爬虫优先抓取商品列表页面,我们在Redis中定义了两个队列(利用Redis的list的lpop和rpush模拟),分别是高优先级队列和低优先级队列,我们有更高优先级的商品列表page存放在队列中,商品详情页存放在低优先级队列中。这样我们就可以保证爬虫在抓取数据时,会优先从高优先级队列中抓取数据,从而让爬虫优先抓取商品列表页面。
package cn.mrchor.spider.utils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
public class JedisUtils {
public static String highKey = "jd_high_key";
public static String lowKey = "jd_low_key";
private JedisPool jedisPool = null;
/**
* 构造函数初始化jedis数据库连接池
*/
public JedisUtils() {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxIdle(10);
jedisPoolConfig.setMaxTotal(100);
jedisPoolConfig.setMaxWaitMillis(10000);
jedisPoolConfig.setTestOnBorrow(true);
jedisPool = new JedisPool("192.168.52.128", 6379);
}
/**
* 获取jedis对象操作jedis数据库
* @return
*/
public Jedis getJedis() {
return this.jedisPool.getResource();
}
/**
* 往list添加数据
*/
public void addUrl(String key, String url) {
Jedis jedis = jedisPool.getResource();
jedis.lpush(key, url);
jedisPool.returnResourceObject(jedis);
}
/**
* 从list中取数据
*/
public String getUrl(String key) {
Jedis jedis = jedisPool.getResource();
String url = jedis.rpop(key);
jedisPool.returnResourceObject(jedis);
return url;
}
} 查看全部
httpclient 抓取网页(某电商商品详细信息的整体架构布局(图)、业务需求
)
HtmlCleaner&xPath:网页分析软件,解析出需要的相关信息。
MySQL数据库:用于存储爬取到的产品的详细信息。
ZooKeeper:分布式协调工具,用于监控后期各个爬虫的运行状态。
三、业务需求
获取电子商务产品的详细信息,需要的相关字段有:产品ID、产品名称、产品价格和产品详细信息。
四、 整体结构布局
第一个是我们的核心部件爬虫程序。爬虫过程是:从Redis数据仓库中取出URL,使用HttpClient进行下载,下载的页面内容,我们使用HtmlCleaner和xPath进行页面分析,此时我们解析的页面可能是产品列表页面,或者它可能是产品的详细页面。如果是产品列表页面,则需要在页面中解析出产品详情页面的URL,放入Redis数据仓库进行后期分析;如果是产品详细信息页面,请将其存储在我们的 MySQL 数据中。具体架构图如下:
核心程序爬虫写好后,为了加快页面爬取效率,我们需要对爬虫进行改进:一是爬虫程序多线程化;二是将爬虫部署到多台服务器上,进一步加快爬虫的爬取效率。在实际生产环境中,由于刀片服务器稳定性较差,可能会出现一些问题,例如:爬虫进程挂掉。这些问题可能经常发生,所以我们需要对其进行监控。一旦发现爬虫进程挂掉,立即启动脚本重启爬虫进程,保证我们整个爬虫核心的持续运行。这是我们的分布式协调服务 ZooKeeper 的使用。我们可以再写一个进程监控程序,实时监控爬虫的运行状态。原理是:爬虫启动时,在ZooKeeper服务中注册自己的临时目录,监控程序使用ZooKeeper对爬虫注册的临时目录进行监控。ZooKeeper的本质——如果注册临时目录的程序挂了,过一会临时目录就会消失。利用这种性质,我们的监控程序监控爬虫注册的临时目录。一旦发现临时目录消失,服务器就会发生变化。其上的爬虫进程已经暂停,所以我们需要启动脚本来重启爬虫进程。然后我们将捕获的产品的详细信息存储在我们的分布式 MySQL 数据库中。以下是整个爬虫项目的架构图:它在ZooKeeper服务中注册了自己的临时目录,监控程序使用ZooKeeper来监控爬虫注册的临时目录。ZooKeeper的本质——如果注册临时目录的程序挂了,过一会临时目录就会消失。利用这种性质,我们的监控程序监控爬虫注册的临时目录。一旦发现临时目录消失,服务器就会发生变化。其上的爬虫进程已经暂停,所以我们需要启动脚本来重启爬虫进程。然后我们将捕获的产品的详细信息存储在我们的分布式 MySQL 数据库中。以下是整个爬虫项目的架构图:它在ZooKeeper服务中注册了自己的临时目录,监控程序使用ZooKeeper来监控爬虫注册的临时目录。ZooKeeper的本质——如果注册临时目录的程序挂了,过一会临时目录就会消失。利用这种性质,我们的监控程序监控爬虫注册的临时目录。一旦发现临时目录消失,服务器就会发生变化。其上的爬虫进程已经暂停,所以我们需要启动脚本来重启爬虫进程。然后我们将捕获的产品的详细信息存储在我们的分布式 MySQL 数据库中。以下是整个爬虫项目的架构图:监控程序使用ZooKeeper监控爬虫注册的临时目录。ZooKeeper的本质——如果注册临时目录的程序挂了,过一会临时目录就会消失。利用这种性质,我们的监控程序监控爬虫注册的临时目录。一旦发现临时目录消失,服务器就会发生变化。其上的爬虫进程已经暂停,所以我们需要启动脚本来重启爬虫进程。然后我们将捕获的产品的详细信息存储在我们的分布式 MySQL 数据库中。以下是整个爬虫项目的架构图:监控程序使用ZooKeeper监控爬虫注册的临时目录。ZooKeeper的本质——如果注册临时目录的程序挂了,过一会临时目录就会消失。利用这种性质,我们的监控程序监控爬虫注册的临时目录。一旦发现临时目录消失,服务器就会发生变化。其上的爬虫进程已经暂停,所以我们需要启动脚本来重启爬虫进程。然后我们将捕获的产品的详细信息存储在我们的分布式 MySQL 数据库中。以下是整个爬虫项目的架构图:ZooKeeper的本质——如果注册临时目录的程序挂了,过一会临时目录就会消失。利用这种性质,我们的监控程序监控爬虫注册的临时目录。一旦发现临时目录消失,服务器就会发生变化。其上的爬虫进程已经暂停,所以我们需要启动脚本来重启爬虫进程。然后我们将捕获的产品的详细信息存储在我们的分布式 MySQL 数据库中。以下是整个爬虫项目的架构图:ZooKeeper的本质——如果注册临时目录的程序挂了,过一会临时目录就会消失。利用这种性质,我们的监控程序监控爬虫注册的临时目录。一旦发现临时目录消失,服务器就会发生变化。其上的爬虫进程已经暂停,所以我们需要启动脚本来重启爬虫进程。然后我们将捕获的产品的详细信息存储在我们的分布式 MySQL 数据库中。以下是整个爬虫项目的架构图:服务器将被更改。其上的爬虫进程已经暂停,所以我们需要启动脚本来重启爬虫进程。然后我们将捕获的产品的详细信息存储在我们的分布式 MySQL 数据库中。以下是整个爬虫项目的架构图:服务器将被更改。其上的爬虫进程已经暂停,所以我们需要启动脚本来重启爬虫进程。然后我们将捕获的产品的详细信息存储在我们的分布式 MySQL 数据库中。以下是整个爬虫项目的架构图:
接下来,我们将重点分析爬虫架构的各个部分。
五、Redis 数据库-临时存储要爬取的 URL。
Redis 数据库是一个基于内存的 Key-Value 非关系型数据库。由于其极快的读写速度,受到了人们的热烈追捧(读写速度约为每秒10W)。Redis 数据库用于临时数据存储的选择就是基于此。为了让我们的爬虫优先抓取商品列表页面,我们在Redis中定义了两个队列(利用Redis的list的lpop和rpush模拟),分别是高优先级队列和低优先级队列,我们有更高优先级的商品列表page存放在队列中,商品详情页存放在低优先级队列中。这样我们就可以保证爬虫在抓取数据时,会优先从高优先级队列中抓取数据,从而让爬虫优先抓取商品列表页面。
package cn.mrchor.spider.utils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
public class JedisUtils {
public static String highKey = "jd_high_key";
public static String lowKey = "jd_low_key";
private JedisPool jedisPool = null;
/**
* 构造函数初始化jedis数据库连接池
*/
public JedisUtils() {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxIdle(10);
jedisPoolConfig.setMaxTotal(100);
jedisPoolConfig.setMaxWaitMillis(10000);
jedisPoolConfig.setTestOnBorrow(true);
jedisPool = new JedisPool("192.168.52.128", 6379);
}
/**
* 获取jedis对象操作jedis数据库
* @return
*/
public Jedis getJedis() {
return this.jedisPool.getResource();
}
/**
* 往list添加数据
*/
public void addUrl(String key, String url) {
Jedis jedis = jedisPool.getResource();
jedis.lpush(key, url);
jedisPool.returnResourceObject(jedis);
}
/**
* 从list中取数据
*/
public String getUrl(String key) {
Jedis jedis = jedisPool.getResource();
String url = jedis.rpop(key);
jedisPool.returnResourceObject(jedis);
return url;
}
}
httpclient 抓取网页(做过j2ee或android开发的童鞋,应该或多或少都使用过Apeache)
网站优化 • 优采云 发表了文章 • 0 个评论 • 76 次浏览 • 2021-09-24 10:53
做过j2ee或者android开发的童鞋,应该或多或少用过Apeache的HttpClient库。这个类库为我们提供了非常强大的服务端Http请求操作。在开发中使用非常方便。
最近在php的发展中,也有需要在服务端发送http请求,然后处理返回给客户端。如果用socket来做,可能不会太麻烦。我想看看php中有没有像HttpClient这样的库。
我google了一下,发现PHP中有这样一个库,名字叫httpclient。我很兴奋。看了官网,发现很多年没更新了,功能好像也有限。我很失望。然后我找到了另一个图书馆,史努比。我对这个库一无所知,但是网上反响很好,所以我决定使用它。他的API用法和Apeache的HttpClient有很大的不同,但是还是非常好用的。它还提供了很多特殊用途的方法,比如只抓取页面上的表单表单,或者所有的链接等等。
include 'Snoopy.class.php';
$snoopy = new Snoopy();
$snoopy->fetch("http://www.baidu.com");
echo $snoopy->results;
有了上面几行代码,就可以轻松抓取百度的页面了。
当然,当需要发送post表单时,可以使用submit方法提交数据。
同时他还传递了请求头,对应的头以及Cookie的相关操作功能,非常强大。
include "Snoopy.class.php";
$snoopy = new Snoopy();
$snoopy->proxy_host = "http://www.baidu.cn";
$snoopy->proxy_port = "80";
$snoopy->agent = "(compatible; MSIE 4.01; MSN 2.5; AOL 4.0; Windows 98)";
$snoopy->referer = "http://www.4wei.cn";
$snoopy->cookies["SessionID"] = '238472834723489';
$snoopy->cookies["favoriteColor"] = "RED";
$snoopy->rawheaders["Pragma"] = "no-cache";
$snoopy->maxredirs = 2;
$snoopy->offsiteok = false;
$snoopy->expandlinks = false;
$snoopy->user = "joe";
$snoopy->pass = "bloe";
if($snoopy->fetchtext("http://www.baidu.cn")) {
echo "" . htmlspecialchars($snoopy->results) . "
\n";} else {echo "error fetching document: ". $snoopy->error. "\n";}
更多操作方法可以去史努比官方文档,或者直接查看源码。
此时,snoopy 只是将页面取回。如果您想从获取的页面中提取数据,那么它不会有太大帮助。在这里我找到了另一个很好的php解析HTML的工具:phpQuery,它提供了和jquery几乎一样的操作方法,并且提供了一些php的特性。对于熟悉jquery的小朋友来说,使用phpquery应该是相当容易的,甚至phpQuery的文件都不需要了。。
使用Snoopy+PhpQuery可以轻松实现网页抓取和数据分析。这是非常有用的。最近也有这方面的需求,发现了这两个不错的库。Java 可以做很多事情。php也可以。
有兴趣的同学也可以尝试用它们来制作一个简单的网络爬虫。
免责声明:本文原创发表于php中文网。转载请注明出处。感谢您的尊重!如果您有任何疑问,请与我们联系 查看全部
httpclient 抓取网页(做过j2ee或android开发的童鞋,应该或多或少都使用过Apeache)
做过j2ee或者android开发的童鞋,应该或多或少用过Apeache的HttpClient库。这个类库为我们提供了非常强大的服务端Http请求操作。在开发中使用非常方便。
最近在php的发展中,也有需要在服务端发送http请求,然后处理返回给客户端。如果用socket来做,可能不会太麻烦。我想看看php中有没有像HttpClient这样的库。
我google了一下,发现PHP中有这样一个库,名字叫httpclient。我很兴奋。看了官网,发现很多年没更新了,功能好像也有限。我很失望。然后我找到了另一个图书馆,史努比。我对这个库一无所知,但是网上反响很好,所以我决定使用它。他的API用法和Apeache的HttpClient有很大的不同,但是还是非常好用的。它还提供了很多特殊用途的方法,比如只抓取页面上的表单表单,或者所有的链接等等。
include 'Snoopy.class.php';
$snoopy = new Snoopy();
$snoopy->fetch("http://www.baidu.com");
echo $snoopy->results;
有了上面几行代码,就可以轻松抓取百度的页面了。
当然,当需要发送post表单时,可以使用submit方法提交数据。
同时他还传递了请求头,对应的头以及Cookie的相关操作功能,非常强大。
include "Snoopy.class.php";
$snoopy = new Snoopy();
$snoopy->proxy_host = "http://www.baidu.cn";
$snoopy->proxy_port = "80";
$snoopy->agent = "(compatible; MSIE 4.01; MSN 2.5; AOL 4.0; Windows 98)";
$snoopy->referer = "http://www.4wei.cn";
$snoopy->cookies["SessionID"] = '238472834723489';
$snoopy->cookies["favoriteColor"] = "RED";
$snoopy->rawheaders["Pragma"] = "no-cache";
$snoopy->maxredirs = 2;
$snoopy->offsiteok = false;
$snoopy->expandlinks = false;
$snoopy->user = "joe";
$snoopy->pass = "bloe";
if($snoopy->fetchtext("http://www.baidu.cn")) {
echo "" . htmlspecialchars($snoopy->results) . "
\n";} else {echo "error fetching document: ". $snoopy->error. "\n";}
更多操作方法可以去史努比官方文档,或者直接查看源码。
此时,snoopy 只是将页面取回。如果您想从获取的页面中提取数据,那么它不会有太大帮助。在这里我找到了另一个很好的php解析HTML的工具:phpQuery,它提供了和jquery几乎一样的操作方法,并且提供了一些php的特性。对于熟悉jquery的小朋友来说,使用phpquery应该是相当容易的,甚至phpQuery的文件都不需要了。。
使用Snoopy+PhpQuery可以轻松实现网页抓取和数据分析。这是非常有用的。最近也有这方面的需求,发现了这两个不错的库。Java 可以做很多事情。php也可以。
有兴趣的同学也可以尝试用它们来制作一个简单的网络爬虫。

免责声明:本文原创发表于php中文网。转载请注明出处。感谢您的尊重!如果您有任何疑问,请与我们联系
httpclient 抓取网页(如何编写爬虫程序爬取网络上有价值的数据信息)
网站优化 • 优采云 发表了文章 • 0 个评论 • 83 次浏览 • 2021-09-22 14:07
随着互联网+时代的层出不穷,越来越多的互联网企业层出不穷,涉及到游戏、视频、新闻、社交网络、电商、房地产、旅游等诸多行业。如今,互联网已经成为了大量信息的载体。如何有效地从信息中提取有价值的信息并加以利用已成为一个巨大的挑战
爬虫,一个可怕的怪物,自百度和谷歌等搜索引擎公司诞生以来就一直存在。如今,在移动互联网时代,爬虫变得更加猖獗。每个人网站似乎都被它光顾过,但你看不到它。但是,您可以放心,它不会做坏事。您可以快速搜索您在互联网上找到的信息,这应该是它的功劳,采集互联网每天都为每个人提供丰富的信息以供查询和共享。Java作为互联网发展的主流语言,在互联网领域得到了广泛的应用。本课程使用Java技术解释如何编写爬虫程序来爬网网络上有价值的数据信息
知识点1.crawler简介
当我们访问网页时,在地址栏中输入URL并按enter键。网站服务器将向我们返回一个HTML文件。浏览器将解析返回的数据并将其显示在UI上。同样,爬虫也会模仿人类的操作,向网站发送请求,网站会向爬虫返回一个HTML文件,爬虫会抓取并分析返回的数据
爬行动物简介
1.1爬行动物简介
网络爬虫,也称为网络蜘蛛自动索引器,是一种“自动浏览网络”的程序,或网络机器人
爬虫广泛应用于互联网搜索引擎或其他类似的网站中,以获取或更新这些网站内容和检索方法。他们可以自动采集所有他们可以访问的页面内容,以便通过搜索引擎进行进一步处理(对下载的页面进行排序和排序),以便用户能够更快地检索到他们需要的信息
一般来说,手动打开窗口、输入数据等都是为了替换操作程序,使用该程序为您获取所需信息,这是一个网络爬虫
1.2爬虫应用程序1.2.1搜索引擎
爬虫程序可以为搜索引擎系统抓取网络资源,用户可以通过搜索引擎搜索网络上所需的所有资源。搜索引擎是一个非常庞大而精确的算法系统,搜索精度和效率对搜索系统都有很高的要求
搜索引擎原理
1.@@2.2数据挖掘
大数据分析
除了搜索,爬虫还可以做很多工作。可以说,爬虫现在广泛应用于互联网项目中
互联网项目主要进行数据分析,通过抓取相关数据获取价值数据。然后,爬虫可以这样做。以下是一个简单的理解:
应用程序下载分析1.3爬行动物原理1.3.1爬虫目
一般来说,我们需要捕获网站或应用程序的内容,提取有用的价值并进行数据分析
1.@3.2履带架设计
为了便于开发,本项目中也可以使用爬虫框架开发爬虫;通用网络爬虫框架如图所示:
Web crawler framework.png
网络爬虫的基本工作流程如下:
首先,选择一些精心挑选的种子URL,将这些URL放入要爬网的URL队列中,从要爬网的URL队列中取出要爬网的URL,解析DNS,获取主机IP,下载URL对应的网页并存储在下载的网页库中。此外,将这些URL放入爬网URL队列,分析爬网URL队列中的URL,分析其他URL,并将URL放入要获取的URL队列,以便进入下一个循环@2.Java crawler framework@2.1坚果
Nutch是一个分布式爬虫,主要解决两个问题:1)海量URL管理和2)网络速度。如果你想成为一个搜索引擎,Nutch1.X是一个很好的选择。Nutch1.X和Solr或ES可以形成一个非常强大的搜索引擎。否则,尽量不要选择nutch作为爬虫程序准备和调试爬虫程序所需的时间通常是单个爬虫程序的十倍以上
@2.2赫里特里克斯
Heritrix是一个“归档爬虫”——用于获取站点内容的完整、准确和深入复制,包括获取图像和其他非文本内容。捕获并存储相关内容。不要拒绝内容,也不要修改页面上的内容。重新爬网不会替换同一URL的上一个URL。爬虫主要通过web用户界面启动、监控和调整,允许弹性定义URL获取
@2.3爬虫4J
Crawler4j是一个用Java实现的开源web爬虫程序。它提供了一个易于使用的界面,可以在几分钟内创建一个多线程网络爬虫
@2.4网络采集器
Webcollector使用nutch的爬行逻辑(分层广度遍历)、crawler4j的用户界面(涵盖访问方法和定义用户操作)和一组自己的插件机制来设计爬虫内核
@2.5网络魔术
webmagic项目代码分为两部分:核心和扩展。核心部分(webmagic core)是一个简化的模块化爬虫实现,而扩展部分收录一些方便实用的功能。webmagic的架构设计参考scratch,目标是尽可能模块化并反映爬虫的功能特性 查看全部
httpclient 抓取网页(如何编写爬虫程序爬取网络上有价值的数据信息)
随着互联网+时代的层出不穷,越来越多的互联网企业层出不穷,涉及到游戏、视频、新闻、社交网络、电商、房地产、旅游等诸多行业。如今,互联网已经成为了大量信息的载体。如何有效地从信息中提取有价值的信息并加以利用已成为一个巨大的挑战
爬虫,一个可怕的怪物,自百度和谷歌等搜索引擎公司诞生以来就一直存在。如今,在移动互联网时代,爬虫变得更加猖獗。每个人网站似乎都被它光顾过,但你看不到它。但是,您可以放心,它不会做坏事。您可以快速搜索您在互联网上找到的信息,这应该是它的功劳,采集互联网每天都为每个人提供丰富的信息以供查询和共享。Java作为互联网发展的主流语言,在互联网领域得到了广泛的应用。本课程使用Java技术解释如何编写爬虫程序来爬网网络上有价值的数据信息
知识点1.crawler简介
当我们访问网页时,在地址栏中输入URL并按enter键。网站服务器将向我们返回一个HTML文件。浏览器将解析返回的数据并将其显示在UI上。同样,爬虫也会模仿人类的操作,向网站发送请求,网站会向爬虫返回一个HTML文件,爬虫会抓取并分析返回的数据
爬行动物简介
1.1爬行动物简介
网络爬虫,也称为网络蜘蛛自动索引器,是一种“自动浏览网络”的程序,或网络机器人
爬虫广泛应用于互联网搜索引擎或其他类似的网站中,以获取或更新这些网站内容和检索方法。他们可以自动采集所有他们可以访问的页面内容,以便通过搜索引擎进行进一步处理(对下载的页面进行排序和排序),以便用户能够更快地检索到他们需要的信息
一般来说,手动打开窗口、输入数据等都是为了替换操作程序,使用该程序为您获取所需信息,这是一个网络爬虫
1.2爬虫应用程序1.2.1搜索引擎
爬虫程序可以为搜索引擎系统抓取网络资源,用户可以通过搜索引擎搜索网络上所需的所有资源。搜索引擎是一个非常庞大而精确的算法系统,搜索精度和效率对搜索系统都有很高的要求
搜索引擎原理
1.@@2.2数据挖掘
大数据分析
除了搜索,爬虫还可以做很多工作。可以说,爬虫现在广泛应用于互联网项目中
互联网项目主要进行数据分析,通过抓取相关数据获取价值数据。然后,爬虫可以这样做。以下是一个简单的理解:
应用程序下载分析1.3爬行动物原理1.3.1爬虫目
一般来说,我们需要捕获网站或应用程序的内容,提取有用的价值并进行数据分析
1.@3.2履带架设计
为了便于开发,本项目中也可以使用爬虫框架开发爬虫;通用网络爬虫框架如图所示:
Web crawler framework.png
网络爬虫的基本工作流程如下:
首先,选择一些精心挑选的种子URL,将这些URL放入要爬网的URL队列中,从要爬网的URL队列中取出要爬网的URL,解析DNS,获取主机IP,下载URL对应的网页并存储在下载的网页库中。此外,将这些URL放入爬网URL队列,分析爬网URL队列中的URL,分析其他URL,并将URL放入要获取的URL队列,以便进入下一个循环@2.Java crawler framework@2.1坚果
Nutch是一个分布式爬虫,主要解决两个问题:1)海量URL管理和2)网络速度。如果你想成为一个搜索引擎,Nutch1.X是一个很好的选择。Nutch1.X和Solr或ES可以形成一个非常强大的搜索引擎。否则,尽量不要选择nutch作为爬虫程序准备和调试爬虫程序所需的时间通常是单个爬虫程序的十倍以上
@2.2赫里特里克斯
Heritrix是一个“归档爬虫”——用于获取站点内容的完整、准确和深入复制,包括获取图像和其他非文本内容。捕获并存储相关内容。不要拒绝内容,也不要修改页面上的内容。重新爬网不会替换同一URL的上一个URL。爬虫主要通过web用户界面启动、监控和调整,允许弹性定义URL获取
@2.3爬虫4J
Crawler4j是一个用Java实现的开源web爬虫程序。它提供了一个易于使用的界面,可以在几分钟内创建一个多线程网络爬虫
@2.4网络采集器
Webcollector使用nutch的爬行逻辑(分层广度遍历)、crawler4j的用户界面(涵盖访问方法和定义用户操作)和一组自己的插件机制来设计爬虫内核
@2.5网络魔术
webmagic项目代码分为两部分:核心和扩展。核心部分(webmagic core)是一个简化的模块化爬虫实现,而扩展部分收录一些方便实用的功能。webmagic的架构设计参考scratch,目标是尽可能模块化并反映爬虫的功能特性
httpclient 抓取网页(1.什么是爬虫?Python最适合写爬虫系统的语言)
网站优化 • 优采云 发表了文章 • 0 个评论 • 65 次浏览 • 2021-09-19 16:23
1.什么是爬行动物?爪哇
引用百度百科全书的话说:“网络爬虫(也称为网络蜘蛛、网络机器人,在FOAF社区更常被称为网络追踪器)是一种程序或脚本,可以根据特定规则自动抓取万维网信息。其他不常用的名称包括蚂蚁、自动索引、模拟程序或蠕虫。”
上面描述了关键信息:自动获取信息的程序或脚本。因此,一般来说,网络爬虫是一种程序或脚本,可以在指定的网络上获取指定类型的信息。程序设计
二.爬行动物能做什么?分段断层
1.search engine:搜索引擎显示的大部分内容是爬虫采集的主要web内容浏览器
2.比价网站:如今,电子商务非常发达,但同一商品在不同电子商务平台上的销售价格实际上是不同的,这就催生了很多比价网站,如折扣、返利、,等等。这些网站实际上使用爬虫来实时监控各种电子商务平台的价格波动。服务器
3.其他类型的数据统计分析,如房价与地段的关系、每日热点新闻类型分析等
三.什么语言可以编写爬虫多线程
通过以上分析,我们可以发现爬行动物是非常有用的。无论是对商业价值还是对我的使用,它都将具有巨大的学习价值。同时发生
那么哪种编程语言适合编写爬虫呢?让我们逐一分析。框架
PHP:语言简单,功能模块齐全,但并发性差
Python:各种爬虫框架,良好的多线程支持和gae支持
Java:与脚本语言相比,它更麻烦,但对于复杂的爬虫系统它有优势
C++:各种成本都比较高
从上面的分析可以看出,Python应该是最适合编写爬虫程序的语言,而Java是最适合复杂爬虫系统的语言。然后,本文文章将引导您感受一些使用Java语言的爬虫程序的魅力
4:所需知识:URL
1.什么是URL
爬虫从网页中抓取内容。这个过程称为抓取网页,爬虫程序抓取网页
和我们通常使用IE浏览器浏览网页是一样的。例如,在任何浏览器地址栏中输入:
打开网页的过程实际上是浏览器作为客户端向服务器发送请求。接收到请求后,服务器将相应的内容响应到浏览器。我们看到,内容是浏览器解析来自服务器的响应内容后的效果。甚至我们也可以直接从服务器上查看相应的源代码。以chrome为例,右键点击网页显示网页源代码(如下图所示)
您将看到以下内容:
在上面的例子中,我们在浏览器地址栏中输入:这个字符串是URL
定义为:统一资源定位器
当我通过浏览器时,我看到所有内容都是存储在服务器中的资源(例如图片、文本、视频剪辑…),以及如何指定要访问的特定资源,即使用URL来指定,这也是URL存在的含义,以及为什么称之为统一资源定位器。“资源”和“位置”这两个词非常重要
2.URL语法格式:
URL由三部分组成: 查看全部
httpclient 抓取网页(1.什么是爬虫?Python最适合写爬虫系统的语言)
1.什么是爬行动物?爪哇
引用百度百科全书的话说:“网络爬虫(也称为网络蜘蛛、网络机器人,在FOAF社区更常被称为网络追踪器)是一种程序或脚本,可以根据特定规则自动抓取万维网信息。其他不常用的名称包括蚂蚁、自动索引、模拟程序或蠕虫。”
上面描述了关键信息:自动获取信息的程序或脚本。因此,一般来说,网络爬虫是一种程序或脚本,可以在指定的网络上获取指定类型的信息。程序设计
二.爬行动物能做什么?分段断层
1.search engine:搜索引擎显示的大部分内容是爬虫采集的主要web内容浏览器
2.比价网站:如今,电子商务非常发达,但同一商品在不同电子商务平台上的销售价格实际上是不同的,这就催生了很多比价网站,如折扣、返利、,等等。这些网站实际上使用爬虫来实时监控各种电子商务平台的价格波动。服务器
3.其他类型的数据统计分析,如房价与地段的关系、每日热点新闻类型分析等
三.什么语言可以编写爬虫多线程
通过以上分析,我们可以发现爬行动物是非常有用的。无论是对商业价值还是对我的使用,它都将具有巨大的学习价值。同时发生
那么哪种编程语言适合编写爬虫呢?让我们逐一分析。框架
PHP:语言简单,功能模块齐全,但并发性差
Python:各种爬虫框架,良好的多线程支持和gae支持
Java:与脚本语言相比,它更麻烦,但对于复杂的爬虫系统它有优势
C++:各种成本都比较高
从上面的分析可以看出,Python应该是最适合编写爬虫程序的语言,而Java是最适合复杂爬虫系统的语言。然后,本文文章将引导您感受一些使用Java语言的爬虫程序的魅力
4:所需知识:URL
1.什么是URL
爬虫从网页中抓取内容。这个过程称为抓取网页,爬虫程序抓取网页
和我们通常使用IE浏览器浏览网页是一样的。例如,在任何浏览器地址栏中输入:
打开网页的过程实际上是浏览器作为客户端向服务器发送请求。接收到请求后,服务器将相应的内容响应到浏览器。我们看到,内容是浏览器解析来自服务器的响应内容后的效果。甚至我们也可以直接从服务器上查看相应的源代码。以chrome为例,右键点击网页显示网页源代码(如下图所示)
您将看到以下内容:
在上面的例子中,我们在浏览器地址栏中输入:这个字符串是URL
定义为:统一资源定位器
当我通过浏览器时,我看到所有内容都是存储在服务器中的资源(例如图片、文本、视频剪辑…),以及如何指定要访问的特定资源,即使用URL来指定,这也是URL存在的含义,以及为什么称之为统一资源定位器。“资源”和“位置”这两个词非常重要
2.URL语法格式:
URL由三部分组成:
httpclient 抓取网页(如何开发一个Java爬虫(的设计机制及原理))
网站优化 • 优采云 发表了文章 • 0 个评论 • 110 次浏览 • 2021-09-17 17:08
最近在写一个小爬虫,准备爬一部分网页数据,来做模型训练,在考虑如何抓取网页及分析网页时,参考了OSC站中一些项目,特别是@黄亿华写的《webmagic的设计机制及原理-如何开发一个Java爬虫》这篇文章给了不少启发,webmagic是一个垂直的爬虫,而我要写的是一个比较通用的爬虫,主要爬起中文的网站的内容,对于HTTP协议及报文的处理,没有比HttpClient组件更好的选择了,对于HTML代码的解析,在比较HTMLParser和Jsoup后,后者在API的使用上优势明显,简洁易懂。所使用的开源组件定下来后,接着开始思考如何抓取和解析这两个基本功能。
对于我的爬虫抓取这部分功能来说,只要根据网页的URL抓取HTML代码,再从HTML代码中的解析出链接和
标签的文本即可以,因此解析的结果可以用一个Page类来表示,这个类纯粹是一个POJO,那么如何使用HttpClient和Jsoup直接解析成Page对象?
在HttpClient 4.2中,提供了ResponseHandler这个接口来负责处理HttpResponse,因此,借助实现这个接口,可以所返回的HTML代码解析成所需要的Page对象,主要的思路是先把HttpResponse中的数据读出来,变换成HTML代码,然后再用jsoup解析
标签和标签。代码如下,
public class PageResponseHandler implements ResponseHandler
{
private Page page;
public PageResponseHandler(Page page) {
this.page = page;
}
public void setPage(Page page) {
this.page = page;
}
public Page getPage() {
return page;
}
@Override
public Page handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
StatusLine statusLine = response.getStatusLine();
HttpEntity entity = response.getEntity();
if (statusLine.getStatusCode() >= 300) {
EntityUtils.consume(entity);
throw new HttpResponseException(statusLine.getStatusCode(), statusLine.getReasonPhrase());
}
if (entity == null)
return null;
// 利用HTTPClient自带的EntityUtils把当前HttpResponse中的HttpEntity转化成HTML代码
String html = EntityUtils.toString(entity);
Document document = Jsoup.parse(html);
Elements links = document.getElementsByTag("a");
for (int i = 0; i < links.size(); i++) {
Element link = links.get(i);
page.addAnchor(link.attr("href"), link.text());
}
// parse context of plain text from HTML code,
Elements paragraphs = document.getElementsByTag("p");
StringBuffer plainText = new StringBuffer(html.length() / 2);
for (int i = 0; i < paragraphs.size(); i++) {
Element paragraph = paragraphs.get(i);
plainText.append(paragraph.text()).append("\n");
}
page.setPlainText(plainText.toString());
return page;
}
}
代码不超过40行,非常简单,现在可以直接返回Page对象了,写一个测试类,来测试这个PageResponseHandler.测试这个类的功能也不需要复杂的代码。
public class PageResponseHandlerTest {
HttpClient httpclient;
PageResponseHandler pageResponseHandler;
final String url = "http://news.163.com/13/0903/11 ... 3B%3B
Page page = new Page(url);
@Before
public void setUp() throws Exception {
httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet(url);
pageResponseHandler = new PageResponseHandler(page);
httpclient.execute(httpget, pageResponseHandler);
}
@After
public void tearDown() throws Exception {
httpclient.getConnectionManager().shutdown();
}
@Test
public void test() {
System.out.println(page.getPlainText());
assertTrue(page.getPlainText().length() > 0);
assertTrue(page.getAnchors().size() > 0);
}
}
到目前为止,这个爬虫中的抓取和分析功能部分都工作的很好,对于中文,也能很好的解析,比较细心的读者会看到,这些代码中并没有设置字符集,也没有进行字符集进行转换,稍后会讲到HttpClient 4.2组件中字符集的处理。
先回顾一下关于HTTP协议的RFC规范中Content-Type作用,它指明发送给接收者Http Entity内容的媒介类型,对于文本类型的HttpEntity而言,它通常是下面的形式,指定HttpEntity的媒介类型,使用了何种字符集进行编码的,此外RFC规范还规定了,在Content-Type没有指定字符集的情况,默认使用ISO-8859-1字符集对Http Entity进行编码
1
Content-Type: text/html; charset=UTF-8
说到这里,大家应该能猜到HttpClient 4.2是如何能正确的进行编码的----就是利用Content-Type头中所收录的字符集作为编码的输入源。具体的代码可以看EntityUtils这个类的第212行开始的代码。EntityUtils首先从HttpEntity对象中获取Content-Type, 如果Content-Type的字符集不为空,则使用Content-Type对象中指定的字符集进行编码,否则使用开发者指定的字符集进行编码,如果开发者也没有指定字符集,使用默认的字符集iso-8859-1进行编码,当然编码实现,还是调用JDK的Reader类。
ContentType contentType = ContentType.getOrDefault(entity);
Charset charset = contentType.getCharset();
if (charset == null) {
charset = defaultCharset;
}
if (charset == null) { 查看全部
httpclient 抓取网页(如何开发一个Java爬虫(的设计机制及原理))
最近在写一个小爬虫,准备爬一部分网页数据,来做模型训练,在考虑如何抓取网页及分析网页时,参考了OSC站中一些项目,特别是@黄亿华写的《webmagic的设计机制及原理-如何开发一个Java爬虫》这篇文章给了不少启发,webmagic是一个垂直的爬虫,而我要写的是一个比较通用的爬虫,主要爬起中文的网站的内容,对于HTTP协议及报文的处理,没有比HttpClient组件更好的选择了,对于HTML代码的解析,在比较HTMLParser和Jsoup后,后者在API的使用上优势明显,简洁易懂。所使用的开源组件定下来后,接着开始思考如何抓取和解析这两个基本功能。
对于我的爬虫抓取这部分功能来说,只要根据网页的URL抓取HTML代码,再从HTML代码中的解析出链接和
标签的文本即可以,因此解析的结果可以用一个Page类来表示,这个类纯粹是一个POJO,那么如何使用HttpClient和Jsoup直接解析成Page对象?
在HttpClient 4.2中,提供了ResponseHandler这个接口来负责处理HttpResponse,因此,借助实现这个接口,可以所返回的HTML代码解析成所需要的Page对象,主要的思路是先把HttpResponse中的数据读出来,变换成HTML代码,然后再用jsoup解析
标签和标签。代码如下,
public class PageResponseHandler implements ResponseHandler
{
private Page page;
public PageResponseHandler(Page page) {
this.page = page;
}
public void setPage(Page page) {
this.page = page;
}
public Page getPage() {
return page;
}
@Override
public Page handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
StatusLine statusLine = response.getStatusLine();
HttpEntity entity = response.getEntity();
if (statusLine.getStatusCode() >= 300) {
EntityUtils.consume(entity);
throw new HttpResponseException(statusLine.getStatusCode(), statusLine.getReasonPhrase());
}
if (entity == null)
return null;
// 利用HTTPClient自带的EntityUtils把当前HttpResponse中的HttpEntity转化成HTML代码
String html = EntityUtils.toString(entity);
Document document = Jsoup.parse(html);
Elements links = document.getElementsByTag("a");
for (int i = 0; i < links.size(); i++) {
Element link = links.get(i);
page.addAnchor(link.attr("href"), link.text());
}
// parse context of plain text from HTML code,
Elements paragraphs = document.getElementsByTag("p");
StringBuffer plainText = new StringBuffer(html.length() / 2);
for (int i = 0; i < paragraphs.size(); i++) {
Element paragraph = paragraphs.get(i);
plainText.append(paragraph.text()).append("\n");
}
page.setPlainText(plainText.toString());
return page;
}
}
代码不超过40行,非常简单,现在可以直接返回Page对象了,写一个测试类,来测试这个PageResponseHandler.测试这个类的功能也不需要复杂的代码。
public class PageResponseHandlerTest {
HttpClient httpclient;
PageResponseHandler pageResponseHandler;
final String url = "http://news.163.com/13/0903/11 ... 3B%3B
Page page = new Page(url);
@Before
public void setUp() throws Exception {
httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet(url);
pageResponseHandler = new PageResponseHandler(page);
httpclient.execute(httpget, pageResponseHandler);
}
@After
public void tearDown() throws Exception {
httpclient.getConnectionManager().shutdown();
}
@Test
public void test() {
System.out.println(page.getPlainText());
assertTrue(page.getPlainText().length() > 0);
assertTrue(page.getAnchors().size() > 0);
}
}
到目前为止,这个爬虫中的抓取和分析功能部分都工作的很好,对于中文,也能很好的解析,比较细心的读者会看到,这些代码中并没有设置字符集,也没有进行字符集进行转换,稍后会讲到HttpClient 4.2组件中字符集的处理。
先回顾一下关于HTTP协议的RFC规范中Content-Type作用,它指明发送给接收者Http Entity内容的媒介类型,对于文本类型的HttpEntity而言,它通常是下面的形式,指定HttpEntity的媒介类型,使用了何种字符集进行编码的,此外RFC规范还规定了,在Content-Type没有指定字符集的情况,默认使用ISO-8859-1字符集对Http Entity进行编码
1
Content-Type: text/html; charset=UTF-8
说到这里,大家应该能猜到HttpClient 4.2是如何能正确的进行编码的----就是利用Content-Type头中所收录的字符集作为编码的输入源。具体的代码可以看EntityUtils这个类的第212行开始的代码。EntityUtils首先从HttpEntity对象中获取Content-Type, 如果Content-Type的字符集不为空,则使用Content-Type对象中指定的字符集进行编码,否则使用开发者指定的字符集进行编码,如果开发者也没有指定字符集,使用默认的字符集iso-8859-1进行编码,当然编码实现,还是调用JDK的Reader类。
ContentType contentType = ContentType.getOrDefault(entity);
Charset charset = contentType.getCharset();
if (charset == null) {
charset = defaultCharset;
}
if (charset == null) {
httpclient 抓取网页( 4)commons-io工具,获取页面或Json5))
网站优化 • 优采云 发表了文章 • 0 个评论 • 60 次浏览 • 2021-10-10 03:22
4)commons-io工具,获取页面或Json5))
4)commons-io 工具,获取页面或者 Json
5) Jsoup工具(一般用于html字段解析),获取页面,非Json返回格式]
----------------------------------------------- ---------------------------------
完整代码:
package com.yeezhao.common.http; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpMethod; import org.apache.commons.httpclient.methods.GetMethod; import org.apache.commons.io.IOUtils; import org.jsoup.Jsoup; /** * http工具对比 * * @author Administrator -> junhong * * 2016年12月27日 */ public class HttpFetchUtil { /** * 获取访问的状态码 * @param request * @return * @throws Exception */ public static int getResponseCode(String request) throws Exception { URL url = new URL(request); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); return conn.getResponseCode(); } /** * 1)JDK自带HTTP连接,获取页面或Json * @param request * @param charset * @return * @throws Exception */ public static String JDKFetch(String request, String charset) throws Exception { URL url = new URL(request); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); //模拟浏览器参数 conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36" + " (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36"); if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) { InputStream input = conn.getInputStream(); StringBuffer sb = new StringBuffer(); BufferedReader reader = new BufferedReader(new InputStreamReader(input, charset)); String s; while ((s = reader.readLine()) != null) { sb.append(s + "\n"); } input.close(); conn.disconnect(); return sb.toString(); } return ""; } /** * 2) JDK自带URL连接,获取页面或Json * @param request * @param charset * @return * @throws Exception */ public static String URLFetch(String request, String charset) throws Exception { URL url = new URL(request); return IOUtils.toString(url.openStream()); } /** * 3)HttpClient Get工具,获取页面或Json * @param url * @param charset * @return * @throws Exception */ public static String httpClientFetch(String url, String charset) throws Exception { // GET HttpClient httpClient = new HttpClient(); httpClient.getParams().setContentCharset(charset); HttpMethod method = new GetMethod(url); httpClient.executeMethod(method); return method.getResponseBodyAsString(); } /** * 4)commons-io工具,获取页面或Json * @param url * @param charset * @return * @throws Exception */ public static String commonsIOFetch(String url, String charset) throws Exception { return IOUtils.toString(new URL(url), charset); } /** * 5) Jsoup工具(通常用于html字段解析),获取页面,非Json返回格式 * @param url * @return * @throws Exception */ public static String jsoupFetch(String url) throws Exception { return Jsoup.parse(new URL(url), 2 * 1000).html(); } }
测试代码:
package com.yeezhao.common.http; import org.junit.After; import org.junit.Before; import org.junit.Test; /** * 测试类 * 3个测试链接: * 1)百科网页 * 2)浏览器模拟获取接口数据 * 3)获取普通接口数据 * @author Administrator -> junhong * * 2016年12月27日 */ public class HttpFetchUtilTest { String seeds[] = {"http://baike.baidu.com/view/1.htm","http://m.ximalaya.com/tracks/26096131.json","http://remyapi.yeezhao.com/api ... ot%3B}; final static String DEFAULT_CHARSET = "UTF-8"; @Before public void setUp() throws Exception { } @After public void tearDown() throws Exception { System.out.println("--- down ---"); } @Test public void testGetResponseCode() throws Exception{ for(String seed:seeds){ int responseCode = HttpFetchUtil.getResponseCode(seed); System.out.println("ret="+responseCode); } } @Test public void testJDKFetch() throws Exception{ for(String seed:seeds){ String ret = HttpFetchUtil.JDKFetch(seed, DEFAULT_CHARSET); System.out.println("ret="+ret); } } @Test public void testURLFetch() throws Exception{ for(String seed:seeds){ String ret = HttpFetchUtil.URLFetch(seed, DEFAULT_CHARSET); System.out.println("ret="+ret); } } @Test public void testHttpClientFetch()throws Exception { for(String seed:seeds){ String ret = HttpFetchUtil.httpClientFetch(seed, DEFAULT_CHARSET); System.out.println("ret="+ret); } } @Test public void testCommonsIOFetch()throws Exception { for(String seed:seeds){ String ret = HttpFetchUtil.commonsIOFetch(seed, DEFAULT_CHARSET); System.out.println("ret="+ret); } } @Test public void testJsoupFetch() throws Exception{ for(String seed:seeds){ String ret = HttpFetchUtil.jsoupFetch(seed); System.out.println("ret="+ret); } } }
附件:相关jar依赖
... org.jsoupjsoup1.7.3 commons-httpclientcommons-httpclient3.1 commons-iocommons-io2.4 ...
以上是Java中HTTP数据捕获的各种方式的详细讲解。更多详情请关注其他相关html中文网站文章! 查看全部
httpclient 抓取网页(
4)commons-io工具,获取页面或Json5))

4)commons-io 工具,获取页面或者 Json

5) Jsoup工具(一般用于html字段解析),获取页面,非Json返回格式]

----------------------------------------------- ---------------------------------
完整代码:
package com.yeezhao.common.http; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpMethod; import org.apache.commons.httpclient.methods.GetMethod; import org.apache.commons.io.IOUtils; import org.jsoup.Jsoup; /** * http工具对比 * * @author Administrator -> junhong * * 2016年12月27日 */ public class HttpFetchUtil { /** * 获取访问的状态码 * @param request * @return * @throws Exception */ public static int getResponseCode(String request) throws Exception { URL url = new URL(request); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); return conn.getResponseCode(); } /** * 1)JDK自带HTTP连接,获取页面或Json * @param request * @param charset * @return * @throws Exception */ public static String JDKFetch(String request, String charset) throws Exception { URL url = new URL(request); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); //模拟浏览器参数 conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36" + " (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36"); if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) { InputStream input = conn.getInputStream(); StringBuffer sb = new StringBuffer(); BufferedReader reader = new BufferedReader(new InputStreamReader(input, charset)); String s; while ((s = reader.readLine()) != null) { sb.append(s + "\n"); } input.close(); conn.disconnect(); return sb.toString(); } return ""; } /** * 2) JDK自带URL连接,获取页面或Json * @param request * @param charset * @return * @throws Exception */ public static String URLFetch(String request, String charset) throws Exception { URL url = new URL(request); return IOUtils.toString(url.openStream()); } /** * 3)HttpClient Get工具,获取页面或Json * @param url * @param charset * @return * @throws Exception */ public static String httpClientFetch(String url, String charset) throws Exception { // GET HttpClient httpClient = new HttpClient(); httpClient.getParams().setContentCharset(charset); HttpMethod method = new GetMethod(url); httpClient.executeMethod(method); return method.getResponseBodyAsString(); } /** * 4)commons-io工具,获取页面或Json * @param url * @param charset * @return * @throws Exception */ public static String commonsIOFetch(String url, String charset) throws Exception { return IOUtils.toString(new URL(url), charset); } /** * 5) Jsoup工具(通常用于html字段解析),获取页面,非Json返回格式 * @param url * @return * @throws Exception */ public static String jsoupFetch(String url) throws Exception { return Jsoup.parse(new URL(url), 2 * 1000).html(); } }
测试代码:
package com.yeezhao.common.http; import org.junit.After; import org.junit.Before; import org.junit.Test; /** * 测试类 * 3个测试链接: * 1)百科网页 * 2)浏览器模拟获取接口数据 * 3)获取普通接口数据 * @author Administrator -> junhong * * 2016年12月27日 */ public class HttpFetchUtilTest { String seeds[] = {"http://baike.baidu.com/view/1.htm","http://m.ximalaya.com/tracks/26096131.json","http://remyapi.yeezhao.com/api ... ot%3B}; final static String DEFAULT_CHARSET = "UTF-8"; @Before public void setUp() throws Exception { } @After public void tearDown() throws Exception { System.out.println("--- down ---"); } @Test public void testGetResponseCode() throws Exception{ for(String seed:seeds){ int responseCode = HttpFetchUtil.getResponseCode(seed); System.out.println("ret="+responseCode); } } @Test public void testJDKFetch() throws Exception{ for(String seed:seeds){ String ret = HttpFetchUtil.JDKFetch(seed, DEFAULT_CHARSET); System.out.println("ret="+ret); } } @Test public void testURLFetch() throws Exception{ for(String seed:seeds){ String ret = HttpFetchUtil.URLFetch(seed, DEFAULT_CHARSET); System.out.println("ret="+ret); } } @Test public void testHttpClientFetch()throws Exception { for(String seed:seeds){ String ret = HttpFetchUtil.httpClientFetch(seed, DEFAULT_CHARSET); System.out.println("ret="+ret); } } @Test public void testCommonsIOFetch()throws Exception { for(String seed:seeds){ String ret = HttpFetchUtil.commonsIOFetch(seed, DEFAULT_CHARSET); System.out.println("ret="+ret); } } @Test public void testJsoupFetch() throws Exception{ for(String seed:seeds){ String ret = HttpFetchUtil.jsoupFetch(seed); System.out.println("ret="+ret); } } }
附件:相关jar依赖
... org.jsoupjsoup1.7.3 commons-httpclientcommons-httpclient3.1 commons-iocommons-io2.4 ...
以上是Java中HTTP数据捕获的各种方式的详细讲解。更多详情请关注其他相关html中文网站文章!
httpclient 抓取网页(如何用httpclient+jsoup实现抓取网页分享(图))
网站优化 • 优采云 发表了文章 • 0 个评论 • 53 次浏览 • 2021-09-28 21:13
和之前的博客一样,我在学习使用httpclient实现网络爬虫的时候,在网上搜索了很多资料,但是httpclient版本是3.1或4.3的之前版本。我使用我自己了解的 httpclient4.5。今天把自己写的httpclient+jsoup的网页爬取分享给大家。
httpclient+jsoup 获取网页非常简单。首先通过httpclient的get方法获取一个网页的所有内容(有不懂的可以看我上一篇get方法的文章),然后通过jsoup获取一个网页的所有内容。解析内容,获取该网页中的所有链接,然后通过get方法获取这些链接中网页的内容,这样我们就可以获取到一个网页下所有链接的网页内容。例如,如果我们得到一个网页,它下面有 50 个链接,我们可以得到 50 个网页。下面是代码,让我们感受一下
获取网址
public class GetUrl {
public static List getUrl(String ur) {
//创建默认的httpClient实例
CloseableHttpClient client = HttpClients.createDefault();
//创建list存放已读取过的页面
List urllist = new ArrayList();
//创建get
HttpGet get=new HttpGet(ur);
//设置连接超时
Builder custom = RequestConfig.custom();
RequestConfig config = custom.setConnectTimeout(5000).setConnectionRequestTimeout(1000).setSocketTimeout(5000).build();
get.setConfig(config);
//设置消息头部
get.setHeader("Accept", "Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
get.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; rv:6.0.2) Gecko/20100101 Firefox/6.0.2");
try {
//执行get请求
CloseableHttpResponse response = client.execute(get);
//获取响应实体
HttpEntity entity = response.getEntity();
//将响应实体转为String类型
String html = EntityUtils.toString(entity);
//通过jsoup将String转为jsoup可处理的文档类型
Document doc = Jsoup.parse(html);
//找到该页面中所有的a标签
Elements links = doc.getElementsByTag("a");
int i=1;
for (Element element : links) {
//获取到a标签中href属性的内容
String url = element.attr("href");
//对href内容进行判断 来判断该内容是否是url
if(url.startsWith("http://blog.csdn.net/") && !urllist.contains(url)){
GetPage.getPage(url);
System.out.println(url);
urllist.add(url);
i++;
}
}
response.close();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return urllist;
}
}
根据获取到的url生成页面
最后,测试类
public class Test {
public static void main(String[] args) {
List list = GetUrl.getUrl("http://blog.csdn.net/");
System.out.println("所写链接内的所有内容");
int i=1;
for (String url : list) {
GetUrl.getUrl(url);
System.out.println("第"+i+"条链接内容");
i++;
}
}
}
以上就是如何使用httpclient+jsoup爬取网页。我希望它会对大家有所帮助。 查看全部
httpclient 抓取网页(如何用httpclient+jsoup实现抓取网页分享(图))
和之前的博客一样,我在学习使用httpclient实现网络爬虫的时候,在网上搜索了很多资料,但是httpclient版本是3.1或4.3的之前版本。我使用我自己了解的 httpclient4.5。今天把自己写的httpclient+jsoup的网页爬取分享给大家。
httpclient+jsoup 获取网页非常简单。首先通过httpclient的get方法获取一个网页的所有内容(有不懂的可以看我上一篇get方法的文章),然后通过jsoup获取一个网页的所有内容。解析内容,获取该网页中的所有链接,然后通过get方法获取这些链接中网页的内容,这样我们就可以获取到一个网页下所有链接的网页内容。例如,如果我们得到一个网页,它下面有 50 个链接,我们可以得到 50 个网页。下面是代码,让我们感受一下
获取网址
public class GetUrl {
public static List getUrl(String ur) {
//创建默认的httpClient实例
CloseableHttpClient client = HttpClients.createDefault();
//创建list存放已读取过的页面
List urllist = new ArrayList();
//创建get
HttpGet get=new HttpGet(ur);
//设置连接超时
Builder custom = RequestConfig.custom();
RequestConfig config = custom.setConnectTimeout(5000).setConnectionRequestTimeout(1000).setSocketTimeout(5000).build();
get.setConfig(config);
//设置消息头部
get.setHeader("Accept", "Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
get.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; rv:6.0.2) Gecko/20100101 Firefox/6.0.2");
try {
//执行get请求
CloseableHttpResponse response = client.execute(get);
//获取响应实体
HttpEntity entity = response.getEntity();
//将响应实体转为String类型
String html = EntityUtils.toString(entity);
//通过jsoup将String转为jsoup可处理的文档类型
Document doc = Jsoup.parse(html);
//找到该页面中所有的a标签
Elements links = doc.getElementsByTag("a");
int i=1;
for (Element element : links) {
//获取到a标签中href属性的内容
String url = element.attr("href");
//对href内容进行判断 来判断该内容是否是url
if(url.startsWith("http://blog.csdn.net/") && !urllist.contains(url)){
GetPage.getPage(url);
System.out.println(url);
urllist.add(url);
i++;
}
}
response.close();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return urllist;
}
}
根据获取到的url生成页面
最后,测试类
public class Test {
public static void main(String[] args) {
List list = GetUrl.getUrl("http://blog.csdn.net/");
System.out.println("所写链接内的所有内容");
int i=1;
for (String url : list) {
GetUrl.getUrl(url);
System.out.println("第"+i+"条链接内容");
i++;
}
}
}
以上就是如何使用httpclient+jsoup爬取网页。我希望它会对大家有所帮助。
httpclient 抓取网页(某电商商品详细信息的整体架构布局(图)、业务需求 )
网站优化 • 优采云 发表了文章 • 0 个评论 • 71 次浏览 • 2021-09-26 14:15
)
HtmlCleaner&xPath:网页分析软件,解析出需要的相关信息。
MySQL数据库:用于存储爬取到的产品的详细信息。
ZooKeeper:分布式协调工具,用于监控后期各个爬虫的运行状态。
三、业务需求
获取电子商务产品的详细信息,需要的相关字段有:产品ID、产品名称、产品价格和产品详细信息。
四、 整体结构布局
第一个是我们的核心部件爬虫程序。爬虫过程是:从Redis数据仓库中取出URL,使用HttpClient进行下载,下载的页面内容,我们使用HtmlCleaner和xPath进行页面分析,此时我们解析的页面可能是产品列表页面,或者它可能是产品的详细页面。如果是产品列表页面,则需要在页面中解析出产品详情页面的URL,放入Redis数据仓库进行后期分析;如果是产品详细信息页面,请将其存储在我们的 MySQL 数据中。具体架构图如下:
核心程序爬虫写好后,为了加快页面爬取效率,我们需要对爬虫进行改进:一是爬虫程序多线程化;二是将爬虫部署到多台服务器上,进一步加快爬虫的爬取效率。在实际生产环境中,由于刀片服务器稳定性较差,可能会出现一些问题,例如:爬虫进程挂掉。这些问题可能经常发生,所以我们需要对其进行监控。一旦发现爬虫进程挂掉,立即启动脚本重启爬虫进程,保证我们整个爬虫核心的持续运行。这是我们的分布式协调服务 ZooKeeper 的使用。我们可以再写一个进程监控程序,实时监控爬虫的运行状态。原理是:爬虫启动时,在ZooKeeper服务中注册自己的临时目录,监控程序使用ZooKeeper对爬虫注册的临时目录进行监控。ZooKeeper的本质——如果注册临时目录的程序挂了,过一会临时目录就会消失。利用这种性质,我们的监控程序监控爬虫注册的临时目录。一旦发现临时目录消失,服务器就会发生变化。其上的爬虫进程已经暂停,所以我们需要启动脚本来重启爬虫进程。然后我们将捕获的产品的详细信息存储在我们的分布式 MySQL 数据库中。以下是整个爬虫项目的架构图:它在ZooKeeper服务中注册了自己的临时目录,监控程序使用ZooKeeper来监控爬虫注册的临时目录。ZooKeeper的本质——如果注册临时目录的程序挂了,过一会临时目录就会消失。利用这种性质,我们的监控程序监控爬虫注册的临时目录。一旦发现临时目录消失,服务器就会发生变化。其上的爬虫进程已经暂停,所以我们需要启动脚本来重启爬虫进程。然后我们将捕获的产品的详细信息存储在我们的分布式 MySQL 数据库中。以下是整个爬虫项目的架构图:它在ZooKeeper服务中注册了自己的临时目录,监控程序使用ZooKeeper来监控爬虫注册的临时目录。ZooKeeper的本质——如果注册临时目录的程序挂了,过一会临时目录就会消失。利用这种性质,我们的监控程序监控爬虫注册的临时目录。一旦发现临时目录消失,服务器就会发生变化。其上的爬虫进程已经暂停,所以我们需要启动脚本来重启爬虫进程。然后我们将捕获的产品的详细信息存储在我们的分布式 MySQL 数据库中。以下是整个爬虫项目的架构图:监控程序使用ZooKeeper监控爬虫注册的临时目录。ZooKeeper的本质——如果注册临时目录的程序挂了,过一会临时目录就会消失。利用这种性质,我们的监控程序监控爬虫注册的临时目录。一旦发现临时目录消失,服务器就会发生变化。其上的爬虫进程已经暂停,所以我们需要启动脚本来重启爬虫进程。然后我们将捕获的产品的详细信息存储在我们的分布式 MySQL 数据库中。以下是整个爬虫项目的架构图:监控程序使用ZooKeeper监控爬虫注册的临时目录。ZooKeeper的本质——如果注册临时目录的程序挂了,过一会临时目录就会消失。利用这种性质,我们的监控程序监控爬虫注册的临时目录。一旦发现临时目录消失,服务器就会发生变化。其上的爬虫进程已经暂停,所以我们需要启动脚本来重启爬虫进程。然后我们将捕获的产品的详细信息存储在我们的分布式 MySQL 数据库中。以下是整个爬虫项目的架构图:ZooKeeper的本质——如果注册临时目录的程序挂了,过一会临时目录就会消失。利用这种性质,我们的监控程序监控爬虫注册的临时目录。一旦发现临时目录消失,服务器就会发生变化。其上的爬虫进程已经暂停,所以我们需要启动脚本来重启爬虫进程。然后我们将捕获的产品的详细信息存储在我们的分布式 MySQL 数据库中。以下是整个爬虫项目的架构图:ZooKeeper的本质——如果注册临时目录的程序挂了,过一会临时目录就会消失。利用这种性质,我们的监控程序监控爬虫注册的临时目录。一旦发现临时目录消失,服务器就会发生变化。其上的爬虫进程已经暂停,所以我们需要启动脚本来重启爬虫进程。然后我们将捕获的产品的详细信息存储在我们的分布式 MySQL 数据库中。以下是整个爬虫项目的架构图:服务器将被更改。其上的爬虫进程已经暂停,所以我们需要启动脚本来重启爬虫进程。然后我们将捕获的产品的详细信息存储在我们的分布式 MySQL 数据库中。以下是整个爬虫项目的架构图:服务器将被更改。其上的爬虫进程已经暂停,所以我们需要启动脚本来重启爬虫进程。然后我们将捕获的产品的详细信息存储在我们的分布式 MySQL 数据库中。以下是整个爬虫项目的架构图:
接下来,我们将重点分析爬虫架构的各个部分。
五、Redis 数据库-临时存储要爬取的 URL。
Redis 数据库是一个基于内存的 Key-Value 非关系型数据库。由于其极快的读写速度,受到了人们的热烈追捧(读写速度约为每秒10W)。Redis 数据库用于临时数据存储的选择就是基于此。为了让我们的爬虫优先抓取商品列表页面,我们在Redis中定义了两个队列(利用Redis的list的lpop和rpush模拟),分别是高优先级队列和低优先级队列,我们有更高优先级的商品列表page存放在队列中,商品详情页存放在低优先级队列中。这样我们就可以保证爬虫在抓取数据时,会优先从高优先级队列中抓取数据,从而让爬虫优先抓取商品列表页面。
package cn.mrchor.spider.utils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
public class JedisUtils {
public static String highKey = "jd_high_key";
public static String lowKey = "jd_low_key";
private JedisPool jedisPool = null;
/**
* 构造函数初始化jedis数据库连接池
*/
public JedisUtils() {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxIdle(10);
jedisPoolConfig.setMaxTotal(100);
jedisPoolConfig.setMaxWaitMillis(10000);
jedisPoolConfig.setTestOnBorrow(true);
jedisPool = new JedisPool("192.168.52.128", 6379);
}
/**
* 获取jedis对象操作jedis数据库
* @return
*/
public Jedis getJedis() {
return this.jedisPool.getResource();
}
/**
* 往list添加数据
*/
public void addUrl(String key, String url) {
Jedis jedis = jedisPool.getResource();
jedis.lpush(key, url);
jedisPool.returnResourceObject(jedis);
}
/**
* 从list中取数据
*/
public String getUrl(String key) {
Jedis jedis = jedisPool.getResource();
String url = jedis.rpop(key);
jedisPool.returnResourceObject(jedis);
return url;
}
} 查看全部
httpclient 抓取网页(某电商商品详细信息的整体架构布局(图)、业务需求
)
HtmlCleaner&xPath:网页分析软件,解析出需要的相关信息。
MySQL数据库:用于存储爬取到的产品的详细信息。
ZooKeeper:分布式协调工具,用于监控后期各个爬虫的运行状态。
三、业务需求
获取电子商务产品的详细信息,需要的相关字段有:产品ID、产品名称、产品价格和产品详细信息。
四、 整体结构布局
第一个是我们的核心部件爬虫程序。爬虫过程是:从Redis数据仓库中取出URL,使用HttpClient进行下载,下载的页面内容,我们使用HtmlCleaner和xPath进行页面分析,此时我们解析的页面可能是产品列表页面,或者它可能是产品的详细页面。如果是产品列表页面,则需要在页面中解析出产品详情页面的URL,放入Redis数据仓库进行后期分析;如果是产品详细信息页面,请将其存储在我们的 MySQL 数据中。具体架构图如下:
核心程序爬虫写好后,为了加快页面爬取效率,我们需要对爬虫进行改进:一是爬虫程序多线程化;二是将爬虫部署到多台服务器上,进一步加快爬虫的爬取效率。在实际生产环境中,由于刀片服务器稳定性较差,可能会出现一些问题,例如:爬虫进程挂掉。这些问题可能经常发生,所以我们需要对其进行监控。一旦发现爬虫进程挂掉,立即启动脚本重启爬虫进程,保证我们整个爬虫核心的持续运行。这是我们的分布式协调服务 ZooKeeper 的使用。我们可以再写一个进程监控程序,实时监控爬虫的运行状态。原理是:爬虫启动时,在ZooKeeper服务中注册自己的临时目录,监控程序使用ZooKeeper对爬虫注册的临时目录进行监控。ZooKeeper的本质——如果注册临时目录的程序挂了,过一会临时目录就会消失。利用这种性质,我们的监控程序监控爬虫注册的临时目录。一旦发现临时目录消失,服务器就会发生变化。其上的爬虫进程已经暂停,所以我们需要启动脚本来重启爬虫进程。然后我们将捕获的产品的详细信息存储在我们的分布式 MySQL 数据库中。以下是整个爬虫项目的架构图:它在ZooKeeper服务中注册了自己的临时目录,监控程序使用ZooKeeper来监控爬虫注册的临时目录。ZooKeeper的本质——如果注册临时目录的程序挂了,过一会临时目录就会消失。利用这种性质,我们的监控程序监控爬虫注册的临时目录。一旦发现临时目录消失,服务器就会发生变化。其上的爬虫进程已经暂停,所以我们需要启动脚本来重启爬虫进程。然后我们将捕获的产品的详细信息存储在我们的分布式 MySQL 数据库中。以下是整个爬虫项目的架构图:它在ZooKeeper服务中注册了自己的临时目录,监控程序使用ZooKeeper来监控爬虫注册的临时目录。ZooKeeper的本质——如果注册临时目录的程序挂了,过一会临时目录就会消失。利用这种性质,我们的监控程序监控爬虫注册的临时目录。一旦发现临时目录消失,服务器就会发生变化。其上的爬虫进程已经暂停,所以我们需要启动脚本来重启爬虫进程。然后我们将捕获的产品的详细信息存储在我们的分布式 MySQL 数据库中。以下是整个爬虫项目的架构图:监控程序使用ZooKeeper监控爬虫注册的临时目录。ZooKeeper的本质——如果注册临时目录的程序挂了,过一会临时目录就会消失。利用这种性质,我们的监控程序监控爬虫注册的临时目录。一旦发现临时目录消失,服务器就会发生变化。其上的爬虫进程已经暂停,所以我们需要启动脚本来重启爬虫进程。然后我们将捕获的产品的详细信息存储在我们的分布式 MySQL 数据库中。以下是整个爬虫项目的架构图:监控程序使用ZooKeeper监控爬虫注册的临时目录。ZooKeeper的本质——如果注册临时目录的程序挂了,过一会临时目录就会消失。利用这种性质,我们的监控程序监控爬虫注册的临时目录。一旦发现临时目录消失,服务器就会发生变化。其上的爬虫进程已经暂停,所以我们需要启动脚本来重启爬虫进程。然后我们将捕获的产品的详细信息存储在我们的分布式 MySQL 数据库中。以下是整个爬虫项目的架构图:ZooKeeper的本质——如果注册临时目录的程序挂了,过一会临时目录就会消失。利用这种性质,我们的监控程序监控爬虫注册的临时目录。一旦发现临时目录消失,服务器就会发生变化。其上的爬虫进程已经暂停,所以我们需要启动脚本来重启爬虫进程。然后我们将捕获的产品的详细信息存储在我们的分布式 MySQL 数据库中。以下是整个爬虫项目的架构图:ZooKeeper的本质——如果注册临时目录的程序挂了,过一会临时目录就会消失。利用这种性质,我们的监控程序监控爬虫注册的临时目录。一旦发现临时目录消失,服务器就会发生变化。其上的爬虫进程已经暂停,所以我们需要启动脚本来重启爬虫进程。然后我们将捕获的产品的详细信息存储在我们的分布式 MySQL 数据库中。以下是整个爬虫项目的架构图:服务器将被更改。其上的爬虫进程已经暂停,所以我们需要启动脚本来重启爬虫进程。然后我们将捕获的产品的详细信息存储在我们的分布式 MySQL 数据库中。以下是整个爬虫项目的架构图:服务器将被更改。其上的爬虫进程已经暂停,所以我们需要启动脚本来重启爬虫进程。然后我们将捕获的产品的详细信息存储在我们的分布式 MySQL 数据库中。以下是整个爬虫项目的架构图:
接下来,我们将重点分析爬虫架构的各个部分。
五、Redis 数据库-临时存储要爬取的 URL。
Redis 数据库是一个基于内存的 Key-Value 非关系型数据库。由于其极快的读写速度,受到了人们的热烈追捧(读写速度约为每秒10W)。Redis 数据库用于临时数据存储的选择就是基于此。为了让我们的爬虫优先抓取商品列表页面,我们在Redis中定义了两个队列(利用Redis的list的lpop和rpush模拟),分别是高优先级队列和低优先级队列,我们有更高优先级的商品列表page存放在队列中,商品详情页存放在低优先级队列中。这样我们就可以保证爬虫在抓取数据时,会优先从高优先级队列中抓取数据,从而让爬虫优先抓取商品列表页面。
package cn.mrchor.spider.utils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
public class JedisUtils {
public static String highKey = "jd_high_key";
public static String lowKey = "jd_low_key";
private JedisPool jedisPool = null;
/**
* 构造函数初始化jedis数据库连接池
*/
public JedisUtils() {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxIdle(10);
jedisPoolConfig.setMaxTotal(100);
jedisPoolConfig.setMaxWaitMillis(10000);
jedisPoolConfig.setTestOnBorrow(true);
jedisPool = new JedisPool("192.168.52.128", 6379);
}
/**
* 获取jedis对象操作jedis数据库
* @return
*/
public Jedis getJedis() {
return this.jedisPool.getResource();
}
/**
* 往list添加数据
*/
public void addUrl(String key, String url) {
Jedis jedis = jedisPool.getResource();
jedis.lpush(key, url);
jedisPool.returnResourceObject(jedis);
}
/**
* 从list中取数据
*/
public String getUrl(String key) {
Jedis jedis = jedisPool.getResource();
String url = jedis.rpop(key);
jedisPool.returnResourceObject(jedis);
return url;
}
}
httpclient 抓取网页(做过j2ee或android开发的童鞋,应该或多或少都使用过Apeache)
网站优化 • 优采云 发表了文章 • 0 个评论 • 76 次浏览 • 2021-09-24 10:53
做过j2ee或者android开发的童鞋,应该或多或少用过Apeache的HttpClient库。这个类库为我们提供了非常强大的服务端Http请求操作。在开发中使用非常方便。
最近在php的发展中,也有需要在服务端发送http请求,然后处理返回给客户端。如果用socket来做,可能不会太麻烦。我想看看php中有没有像HttpClient这样的库。
我google了一下,发现PHP中有这样一个库,名字叫httpclient。我很兴奋。看了官网,发现很多年没更新了,功能好像也有限。我很失望。然后我找到了另一个图书馆,史努比。我对这个库一无所知,但是网上反响很好,所以我决定使用它。他的API用法和Apeache的HttpClient有很大的不同,但是还是非常好用的。它还提供了很多特殊用途的方法,比如只抓取页面上的表单表单,或者所有的链接等等。
include 'Snoopy.class.php';
$snoopy = new Snoopy();
$snoopy->fetch("http://www.baidu.com");
echo $snoopy->results;
有了上面几行代码,就可以轻松抓取百度的页面了。
当然,当需要发送post表单时,可以使用submit方法提交数据。
同时他还传递了请求头,对应的头以及Cookie的相关操作功能,非常强大。
include "Snoopy.class.php";
$snoopy = new Snoopy();
$snoopy->proxy_host = "http://www.baidu.cn";
$snoopy->proxy_port = "80";
$snoopy->agent = "(compatible; MSIE 4.01; MSN 2.5; AOL 4.0; Windows 98)";
$snoopy->referer = "http://www.4wei.cn";
$snoopy->cookies["SessionID"] = '238472834723489';
$snoopy->cookies["favoriteColor"] = "RED";
$snoopy->rawheaders["Pragma"] = "no-cache";
$snoopy->maxredirs = 2;
$snoopy->offsiteok = false;
$snoopy->expandlinks = false;
$snoopy->user = "joe";
$snoopy->pass = "bloe";
if($snoopy->fetchtext("http://www.baidu.cn")) {
echo "" . htmlspecialchars($snoopy->results) . "
\n";} else {echo "error fetching document: ". $snoopy->error. "\n";}
更多操作方法可以去史努比官方文档,或者直接查看源码。
此时,snoopy 只是将页面取回。如果您想从获取的页面中提取数据,那么它不会有太大帮助。在这里我找到了另一个很好的php解析HTML的工具:phpQuery,它提供了和jquery几乎一样的操作方法,并且提供了一些php的特性。对于熟悉jquery的小朋友来说,使用phpquery应该是相当容易的,甚至phpQuery的文件都不需要了。。
使用Snoopy+PhpQuery可以轻松实现网页抓取和数据分析。这是非常有用的。最近也有这方面的需求,发现了这两个不错的库。Java 可以做很多事情。php也可以。
有兴趣的同学也可以尝试用它们来制作一个简单的网络爬虫。
免责声明:本文原创发表于php中文网。转载请注明出处。感谢您的尊重!如果您有任何疑问,请与我们联系 查看全部
httpclient 抓取网页(做过j2ee或android开发的童鞋,应该或多或少都使用过Apeache)
做过j2ee或者android开发的童鞋,应该或多或少用过Apeache的HttpClient库。这个类库为我们提供了非常强大的服务端Http请求操作。在开发中使用非常方便。
最近在php的发展中,也有需要在服务端发送http请求,然后处理返回给客户端。如果用socket来做,可能不会太麻烦。我想看看php中有没有像HttpClient这样的库。
我google了一下,发现PHP中有这样一个库,名字叫httpclient。我很兴奋。看了官网,发现很多年没更新了,功能好像也有限。我很失望。然后我找到了另一个图书馆,史努比。我对这个库一无所知,但是网上反响很好,所以我决定使用它。他的API用法和Apeache的HttpClient有很大的不同,但是还是非常好用的。它还提供了很多特殊用途的方法,比如只抓取页面上的表单表单,或者所有的链接等等。
include 'Snoopy.class.php';
$snoopy = new Snoopy();
$snoopy->fetch("http://www.baidu.com");
echo $snoopy->results;
有了上面几行代码,就可以轻松抓取百度的页面了。
当然,当需要发送post表单时,可以使用submit方法提交数据。
同时他还传递了请求头,对应的头以及Cookie的相关操作功能,非常强大。
include "Snoopy.class.php";
$snoopy = new Snoopy();
$snoopy->proxy_host = "http://www.baidu.cn";
$snoopy->proxy_port = "80";
$snoopy->agent = "(compatible; MSIE 4.01; MSN 2.5; AOL 4.0; Windows 98)";
$snoopy->referer = "http://www.4wei.cn";
$snoopy->cookies["SessionID"] = '238472834723489';
$snoopy->cookies["favoriteColor"] = "RED";
$snoopy->rawheaders["Pragma"] = "no-cache";
$snoopy->maxredirs = 2;
$snoopy->offsiteok = false;
$snoopy->expandlinks = false;
$snoopy->user = "joe";
$snoopy->pass = "bloe";
if($snoopy->fetchtext("http://www.baidu.cn")) {
echo "" . htmlspecialchars($snoopy->results) . "
\n";} else {echo "error fetching document: ". $snoopy->error. "\n";}
更多操作方法可以去史努比官方文档,或者直接查看源码。
此时,snoopy 只是将页面取回。如果您想从获取的页面中提取数据,那么它不会有太大帮助。在这里我找到了另一个很好的php解析HTML的工具:phpQuery,它提供了和jquery几乎一样的操作方法,并且提供了一些php的特性。对于熟悉jquery的小朋友来说,使用phpquery应该是相当容易的,甚至phpQuery的文件都不需要了。。
使用Snoopy+PhpQuery可以轻松实现网页抓取和数据分析。这是非常有用的。最近也有这方面的需求,发现了这两个不错的库。Java 可以做很多事情。php也可以。
有兴趣的同学也可以尝试用它们来制作一个简单的网络爬虫。

免责声明:本文原创发表于php中文网。转载请注明出处。感谢您的尊重!如果您有任何疑问,请与我们联系
httpclient 抓取网页(如何编写爬虫程序爬取网络上有价值的数据信息)
网站优化 • 优采云 发表了文章 • 0 个评论 • 83 次浏览 • 2021-09-22 14:07
随着互联网+时代的层出不穷,越来越多的互联网企业层出不穷,涉及到游戏、视频、新闻、社交网络、电商、房地产、旅游等诸多行业。如今,互联网已经成为了大量信息的载体。如何有效地从信息中提取有价值的信息并加以利用已成为一个巨大的挑战
爬虫,一个可怕的怪物,自百度和谷歌等搜索引擎公司诞生以来就一直存在。如今,在移动互联网时代,爬虫变得更加猖獗。每个人网站似乎都被它光顾过,但你看不到它。但是,您可以放心,它不会做坏事。您可以快速搜索您在互联网上找到的信息,这应该是它的功劳,采集互联网每天都为每个人提供丰富的信息以供查询和共享。Java作为互联网发展的主流语言,在互联网领域得到了广泛的应用。本课程使用Java技术解释如何编写爬虫程序来爬网网络上有价值的数据信息
知识点1.crawler简介
当我们访问网页时,在地址栏中输入URL并按enter键。网站服务器将向我们返回一个HTML文件。浏览器将解析返回的数据并将其显示在UI上。同样,爬虫也会模仿人类的操作,向网站发送请求,网站会向爬虫返回一个HTML文件,爬虫会抓取并分析返回的数据
爬行动物简介
1.1爬行动物简介
网络爬虫,也称为网络蜘蛛自动索引器,是一种“自动浏览网络”的程序,或网络机器人
爬虫广泛应用于互联网搜索引擎或其他类似的网站中,以获取或更新这些网站内容和检索方法。他们可以自动采集所有他们可以访问的页面内容,以便通过搜索引擎进行进一步处理(对下载的页面进行排序和排序),以便用户能够更快地检索到他们需要的信息
一般来说,手动打开窗口、输入数据等都是为了替换操作程序,使用该程序为您获取所需信息,这是一个网络爬虫
1.2爬虫应用程序1.2.1搜索引擎
爬虫程序可以为搜索引擎系统抓取网络资源,用户可以通过搜索引擎搜索网络上所需的所有资源。搜索引擎是一个非常庞大而精确的算法系统,搜索精度和效率对搜索系统都有很高的要求
搜索引擎原理
1.@@2.2数据挖掘
大数据分析
除了搜索,爬虫还可以做很多工作。可以说,爬虫现在广泛应用于互联网项目中
互联网项目主要进行数据分析,通过抓取相关数据获取价值数据。然后,爬虫可以这样做。以下是一个简单的理解:
应用程序下载分析1.3爬行动物原理1.3.1爬虫目
一般来说,我们需要捕获网站或应用程序的内容,提取有用的价值并进行数据分析
1.@3.2履带架设计
为了便于开发,本项目中也可以使用爬虫框架开发爬虫;通用网络爬虫框架如图所示:
Web crawler framework.png
网络爬虫的基本工作流程如下:
首先,选择一些精心挑选的种子URL,将这些URL放入要爬网的URL队列中,从要爬网的URL队列中取出要爬网的URL,解析DNS,获取主机IP,下载URL对应的网页并存储在下载的网页库中。此外,将这些URL放入爬网URL队列,分析爬网URL队列中的URL,分析其他URL,并将URL放入要获取的URL队列,以便进入下一个循环@2.Java crawler framework@2.1坚果
Nutch是一个分布式爬虫,主要解决两个问题:1)海量URL管理和2)网络速度。如果你想成为一个搜索引擎,Nutch1.X是一个很好的选择。Nutch1.X和Solr或ES可以形成一个非常强大的搜索引擎。否则,尽量不要选择nutch作为爬虫程序准备和调试爬虫程序所需的时间通常是单个爬虫程序的十倍以上
@2.2赫里特里克斯
Heritrix是一个“归档爬虫”——用于获取站点内容的完整、准确和深入复制,包括获取图像和其他非文本内容。捕获并存储相关内容。不要拒绝内容,也不要修改页面上的内容。重新爬网不会替换同一URL的上一个URL。爬虫主要通过web用户界面启动、监控和调整,允许弹性定义URL获取
@2.3爬虫4J
Crawler4j是一个用Java实现的开源web爬虫程序。它提供了一个易于使用的界面,可以在几分钟内创建一个多线程网络爬虫
@2.4网络采集器
Webcollector使用nutch的爬行逻辑(分层广度遍历)、crawler4j的用户界面(涵盖访问方法和定义用户操作)和一组自己的插件机制来设计爬虫内核
@2.5网络魔术
webmagic项目代码分为两部分:核心和扩展。核心部分(webmagic core)是一个简化的模块化爬虫实现,而扩展部分收录一些方便实用的功能。webmagic的架构设计参考scratch,目标是尽可能模块化并反映爬虫的功能特性 查看全部
httpclient 抓取网页(如何编写爬虫程序爬取网络上有价值的数据信息)
随着互联网+时代的层出不穷,越来越多的互联网企业层出不穷,涉及到游戏、视频、新闻、社交网络、电商、房地产、旅游等诸多行业。如今,互联网已经成为了大量信息的载体。如何有效地从信息中提取有价值的信息并加以利用已成为一个巨大的挑战
爬虫,一个可怕的怪物,自百度和谷歌等搜索引擎公司诞生以来就一直存在。如今,在移动互联网时代,爬虫变得更加猖獗。每个人网站似乎都被它光顾过,但你看不到它。但是,您可以放心,它不会做坏事。您可以快速搜索您在互联网上找到的信息,这应该是它的功劳,采集互联网每天都为每个人提供丰富的信息以供查询和共享。Java作为互联网发展的主流语言,在互联网领域得到了广泛的应用。本课程使用Java技术解释如何编写爬虫程序来爬网网络上有价值的数据信息
知识点1.crawler简介
当我们访问网页时,在地址栏中输入URL并按enter键。网站服务器将向我们返回一个HTML文件。浏览器将解析返回的数据并将其显示在UI上。同样,爬虫也会模仿人类的操作,向网站发送请求,网站会向爬虫返回一个HTML文件,爬虫会抓取并分析返回的数据
爬行动物简介
1.1爬行动物简介
网络爬虫,也称为网络蜘蛛自动索引器,是一种“自动浏览网络”的程序,或网络机器人
爬虫广泛应用于互联网搜索引擎或其他类似的网站中,以获取或更新这些网站内容和检索方法。他们可以自动采集所有他们可以访问的页面内容,以便通过搜索引擎进行进一步处理(对下载的页面进行排序和排序),以便用户能够更快地检索到他们需要的信息
一般来说,手动打开窗口、输入数据等都是为了替换操作程序,使用该程序为您获取所需信息,这是一个网络爬虫
1.2爬虫应用程序1.2.1搜索引擎
爬虫程序可以为搜索引擎系统抓取网络资源,用户可以通过搜索引擎搜索网络上所需的所有资源。搜索引擎是一个非常庞大而精确的算法系统,搜索精度和效率对搜索系统都有很高的要求
搜索引擎原理
1.@@2.2数据挖掘
大数据分析
除了搜索,爬虫还可以做很多工作。可以说,爬虫现在广泛应用于互联网项目中
互联网项目主要进行数据分析,通过抓取相关数据获取价值数据。然后,爬虫可以这样做。以下是一个简单的理解:
应用程序下载分析1.3爬行动物原理1.3.1爬虫目
一般来说,我们需要捕获网站或应用程序的内容,提取有用的价值并进行数据分析
1.@3.2履带架设计
为了便于开发,本项目中也可以使用爬虫框架开发爬虫;通用网络爬虫框架如图所示:
Web crawler framework.png
网络爬虫的基本工作流程如下:
首先,选择一些精心挑选的种子URL,将这些URL放入要爬网的URL队列中,从要爬网的URL队列中取出要爬网的URL,解析DNS,获取主机IP,下载URL对应的网页并存储在下载的网页库中。此外,将这些URL放入爬网URL队列,分析爬网URL队列中的URL,分析其他URL,并将URL放入要获取的URL队列,以便进入下一个循环@2.Java crawler framework@2.1坚果
Nutch是一个分布式爬虫,主要解决两个问题:1)海量URL管理和2)网络速度。如果你想成为一个搜索引擎,Nutch1.X是一个很好的选择。Nutch1.X和Solr或ES可以形成一个非常强大的搜索引擎。否则,尽量不要选择nutch作为爬虫程序准备和调试爬虫程序所需的时间通常是单个爬虫程序的十倍以上
@2.2赫里特里克斯
Heritrix是一个“归档爬虫”——用于获取站点内容的完整、准确和深入复制,包括获取图像和其他非文本内容。捕获并存储相关内容。不要拒绝内容,也不要修改页面上的内容。重新爬网不会替换同一URL的上一个URL。爬虫主要通过web用户界面启动、监控和调整,允许弹性定义URL获取
@2.3爬虫4J
Crawler4j是一个用Java实现的开源web爬虫程序。它提供了一个易于使用的界面,可以在几分钟内创建一个多线程网络爬虫
@2.4网络采集器
Webcollector使用nutch的爬行逻辑(分层广度遍历)、crawler4j的用户界面(涵盖访问方法和定义用户操作)和一组自己的插件机制来设计爬虫内核
@2.5网络魔术
webmagic项目代码分为两部分:核心和扩展。核心部分(webmagic core)是一个简化的模块化爬虫实现,而扩展部分收录一些方便实用的功能。webmagic的架构设计参考scratch,目标是尽可能模块化并反映爬虫的功能特性
httpclient 抓取网页(1.什么是爬虫?Python最适合写爬虫系统的语言)
网站优化 • 优采云 发表了文章 • 0 个评论 • 65 次浏览 • 2021-09-19 16:23
1.什么是爬行动物?爪哇
引用百度百科全书的话说:“网络爬虫(也称为网络蜘蛛、网络机器人,在FOAF社区更常被称为网络追踪器)是一种程序或脚本,可以根据特定规则自动抓取万维网信息。其他不常用的名称包括蚂蚁、自动索引、模拟程序或蠕虫。”
上面描述了关键信息:自动获取信息的程序或脚本。因此,一般来说,网络爬虫是一种程序或脚本,可以在指定的网络上获取指定类型的信息。程序设计
二.爬行动物能做什么?分段断层
1.search engine:搜索引擎显示的大部分内容是爬虫采集的主要web内容浏览器
2.比价网站:如今,电子商务非常发达,但同一商品在不同电子商务平台上的销售价格实际上是不同的,这就催生了很多比价网站,如折扣、返利、,等等。这些网站实际上使用爬虫来实时监控各种电子商务平台的价格波动。服务器
3.其他类型的数据统计分析,如房价与地段的关系、每日热点新闻类型分析等
三.什么语言可以编写爬虫多线程
通过以上分析,我们可以发现爬行动物是非常有用的。无论是对商业价值还是对我的使用,它都将具有巨大的学习价值。同时发生
那么哪种编程语言适合编写爬虫呢?让我们逐一分析。框架
PHP:语言简单,功能模块齐全,但并发性差
Python:各种爬虫框架,良好的多线程支持和gae支持
Java:与脚本语言相比,它更麻烦,但对于复杂的爬虫系统它有优势
C++:各种成本都比较高
从上面的分析可以看出,Python应该是最适合编写爬虫程序的语言,而Java是最适合复杂爬虫系统的语言。然后,本文文章将引导您感受一些使用Java语言的爬虫程序的魅力
4:所需知识:URL
1.什么是URL
爬虫从网页中抓取内容。这个过程称为抓取网页,爬虫程序抓取网页
和我们通常使用IE浏览器浏览网页是一样的。例如,在任何浏览器地址栏中输入:
打开网页的过程实际上是浏览器作为客户端向服务器发送请求。接收到请求后,服务器将相应的内容响应到浏览器。我们看到,内容是浏览器解析来自服务器的响应内容后的效果。甚至我们也可以直接从服务器上查看相应的源代码。以chrome为例,右键点击网页显示网页源代码(如下图所示)
您将看到以下内容:
在上面的例子中,我们在浏览器地址栏中输入:这个字符串是URL
定义为:统一资源定位器
当我通过浏览器时,我看到所有内容都是存储在服务器中的资源(例如图片、文本、视频剪辑…),以及如何指定要访问的特定资源,即使用URL来指定,这也是URL存在的含义,以及为什么称之为统一资源定位器。“资源”和“位置”这两个词非常重要
2.URL语法格式:
URL由三部分组成: 查看全部
httpclient 抓取网页(1.什么是爬虫?Python最适合写爬虫系统的语言)
1.什么是爬行动物?爪哇
引用百度百科全书的话说:“网络爬虫(也称为网络蜘蛛、网络机器人,在FOAF社区更常被称为网络追踪器)是一种程序或脚本,可以根据特定规则自动抓取万维网信息。其他不常用的名称包括蚂蚁、自动索引、模拟程序或蠕虫。”
上面描述了关键信息:自动获取信息的程序或脚本。因此,一般来说,网络爬虫是一种程序或脚本,可以在指定的网络上获取指定类型的信息。程序设计
二.爬行动物能做什么?分段断层
1.search engine:搜索引擎显示的大部分内容是爬虫采集的主要web内容浏览器
2.比价网站:如今,电子商务非常发达,但同一商品在不同电子商务平台上的销售价格实际上是不同的,这就催生了很多比价网站,如折扣、返利、,等等。这些网站实际上使用爬虫来实时监控各种电子商务平台的价格波动。服务器
3.其他类型的数据统计分析,如房价与地段的关系、每日热点新闻类型分析等
三.什么语言可以编写爬虫多线程
通过以上分析,我们可以发现爬行动物是非常有用的。无论是对商业价值还是对我的使用,它都将具有巨大的学习价值。同时发生
那么哪种编程语言适合编写爬虫呢?让我们逐一分析。框架
PHP:语言简单,功能模块齐全,但并发性差
Python:各种爬虫框架,良好的多线程支持和gae支持
Java:与脚本语言相比,它更麻烦,但对于复杂的爬虫系统它有优势
C++:各种成本都比较高
从上面的分析可以看出,Python应该是最适合编写爬虫程序的语言,而Java是最适合复杂爬虫系统的语言。然后,本文文章将引导您感受一些使用Java语言的爬虫程序的魅力
4:所需知识:URL
1.什么是URL
爬虫从网页中抓取内容。这个过程称为抓取网页,爬虫程序抓取网页
和我们通常使用IE浏览器浏览网页是一样的。例如,在任何浏览器地址栏中输入:
打开网页的过程实际上是浏览器作为客户端向服务器发送请求。接收到请求后,服务器将相应的内容响应到浏览器。我们看到,内容是浏览器解析来自服务器的响应内容后的效果。甚至我们也可以直接从服务器上查看相应的源代码。以chrome为例,右键点击网页显示网页源代码(如下图所示)
您将看到以下内容:
在上面的例子中,我们在浏览器地址栏中输入:这个字符串是URL
定义为:统一资源定位器
当我通过浏览器时,我看到所有内容都是存储在服务器中的资源(例如图片、文本、视频剪辑…),以及如何指定要访问的特定资源,即使用URL来指定,这也是URL存在的含义,以及为什么称之为统一资源定位器。“资源”和“位置”这两个词非常重要
2.URL语法格式:
URL由三部分组成:
httpclient 抓取网页(如何开发一个Java爬虫(的设计机制及原理))
网站优化 • 优采云 发表了文章 • 0 个评论 • 110 次浏览 • 2021-09-17 17:08
最近在写一个小爬虫,准备爬一部分网页数据,来做模型训练,在考虑如何抓取网页及分析网页时,参考了OSC站中一些项目,特别是@黄亿华写的《webmagic的设计机制及原理-如何开发一个Java爬虫》这篇文章给了不少启发,webmagic是一个垂直的爬虫,而我要写的是一个比较通用的爬虫,主要爬起中文的网站的内容,对于HTTP协议及报文的处理,没有比HttpClient组件更好的选择了,对于HTML代码的解析,在比较HTMLParser和Jsoup后,后者在API的使用上优势明显,简洁易懂。所使用的开源组件定下来后,接着开始思考如何抓取和解析这两个基本功能。
对于我的爬虫抓取这部分功能来说,只要根据网页的URL抓取HTML代码,再从HTML代码中的解析出链接和
标签的文本即可以,因此解析的结果可以用一个Page类来表示,这个类纯粹是一个POJO,那么如何使用HttpClient和Jsoup直接解析成Page对象?
在HttpClient 4.2中,提供了ResponseHandler这个接口来负责处理HttpResponse,因此,借助实现这个接口,可以所返回的HTML代码解析成所需要的Page对象,主要的思路是先把HttpResponse中的数据读出来,变换成HTML代码,然后再用jsoup解析
标签和标签。代码如下,
public class PageResponseHandler implements ResponseHandler
{
private Page page;
public PageResponseHandler(Page page) {
this.page = page;
}
public void setPage(Page page) {
this.page = page;
}
public Page getPage() {
return page;
}
@Override
public Page handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
StatusLine statusLine = response.getStatusLine();
HttpEntity entity = response.getEntity();
if (statusLine.getStatusCode() >= 300) {
EntityUtils.consume(entity);
throw new HttpResponseException(statusLine.getStatusCode(), statusLine.getReasonPhrase());
}
if (entity == null)
return null;
// 利用HTTPClient自带的EntityUtils把当前HttpResponse中的HttpEntity转化成HTML代码
String html = EntityUtils.toString(entity);
Document document = Jsoup.parse(html);
Elements links = document.getElementsByTag("a");
for (int i = 0; i < links.size(); i++) {
Element link = links.get(i);
page.addAnchor(link.attr("href"), link.text());
}
// parse context of plain text from HTML code,
Elements paragraphs = document.getElementsByTag("p");
StringBuffer plainText = new StringBuffer(html.length() / 2);
for (int i = 0; i < paragraphs.size(); i++) {
Element paragraph = paragraphs.get(i);
plainText.append(paragraph.text()).append("\n");
}
page.setPlainText(plainText.toString());
return page;
}
}
代码不超过40行,非常简单,现在可以直接返回Page对象了,写一个测试类,来测试这个PageResponseHandler.测试这个类的功能也不需要复杂的代码。
public class PageResponseHandlerTest {
HttpClient httpclient;
PageResponseHandler pageResponseHandler;
final String url = "http://news.163.com/13/0903/11 ... 3B%3B
Page page = new Page(url);
@Before
public void setUp() throws Exception {
httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet(url);
pageResponseHandler = new PageResponseHandler(page);
httpclient.execute(httpget, pageResponseHandler);
}
@After
public void tearDown() throws Exception {
httpclient.getConnectionManager().shutdown();
}
@Test
public void test() {
System.out.println(page.getPlainText());
assertTrue(page.getPlainText().length() > 0);
assertTrue(page.getAnchors().size() > 0);
}
}
到目前为止,这个爬虫中的抓取和分析功能部分都工作的很好,对于中文,也能很好的解析,比较细心的读者会看到,这些代码中并没有设置字符集,也没有进行字符集进行转换,稍后会讲到HttpClient 4.2组件中字符集的处理。
先回顾一下关于HTTP协议的RFC规范中Content-Type作用,它指明发送给接收者Http Entity内容的媒介类型,对于文本类型的HttpEntity而言,它通常是下面的形式,指定HttpEntity的媒介类型,使用了何种字符集进行编码的,此外RFC规范还规定了,在Content-Type没有指定字符集的情况,默认使用ISO-8859-1字符集对Http Entity进行编码
1
Content-Type: text/html; charset=UTF-8
说到这里,大家应该能猜到HttpClient 4.2是如何能正确的进行编码的----就是利用Content-Type头中所收录的字符集作为编码的输入源。具体的代码可以看EntityUtils这个类的第212行开始的代码。EntityUtils首先从HttpEntity对象中获取Content-Type, 如果Content-Type的字符集不为空,则使用Content-Type对象中指定的字符集进行编码,否则使用开发者指定的字符集进行编码,如果开发者也没有指定字符集,使用默认的字符集iso-8859-1进行编码,当然编码实现,还是调用JDK的Reader类。
ContentType contentType = ContentType.getOrDefault(entity);
Charset charset = contentType.getCharset();
if (charset == null) {
charset = defaultCharset;
}
if (charset == null) { 查看全部
httpclient 抓取网页(如何开发一个Java爬虫(的设计机制及原理))
最近在写一个小爬虫,准备爬一部分网页数据,来做模型训练,在考虑如何抓取网页及分析网页时,参考了OSC站中一些项目,特别是@黄亿华写的《webmagic的设计机制及原理-如何开发一个Java爬虫》这篇文章给了不少启发,webmagic是一个垂直的爬虫,而我要写的是一个比较通用的爬虫,主要爬起中文的网站的内容,对于HTTP协议及报文的处理,没有比HttpClient组件更好的选择了,对于HTML代码的解析,在比较HTMLParser和Jsoup后,后者在API的使用上优势明显,简洁易懂。所使用的开源组件定下来后,接着开始思考如何抓取和解析这两个基本功能。
对于我的爬虫抓取这部分功能来说,只要根据网页的URL抓取HTML代码,再从HTML代码中的解析出链接和
标签的文本即可以,因此解析的结果可以用一个Page类来表示,这个类纯粹是一个POJO,那么如何使用HttpClient和Jsoup直接解析成Page对象?
在HttpClient 4.2中,提供了ResponseHandler这个接口来负责处理HttpResponse,因此,借助实现这个接口,可以所返回的HTML代码解析成所需要的Page对象,主要的思路是先把HttpResponse中的数据读出来,变换成HTML代码,然后再用jsoup解析
标签和标签。代码如下,
public class PageResponseHandler implements ResponseHandler
{
private Page page;
public PageResponseHandler(Page page) {
this.page = page;
}
public void setPage(Page page) {
this.page = page;
}
public Page getPage() {
return page;
}
@Override
public Page handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
StatusLine statusLine = response.getStatusLine();
HttpEntity entity = response.getEntity();
if (statusLine.getStatusCode() >= 300) {
EntityUtils.consume(entity);
throw new HttpResponseException(statusLine.getStatusCode(), statusLine.getReasonPhrase());
}
if (entity == null)
return null;
// 利用HTTPClient自带的EntityUtils把当前HttpResponse中的HttpEntity转化成HTML代码
String html = EntityUtils.toString(entity);
Document document = Jsoup.parse(html);
Elements links = document.getElementsByTag("a");
for (int i = 0; i < links.size(); i++) {
Element link = links.get(i);
page.addAnchor(link.attr("href"), link.text());
}
// parse context of plain text from HTML code,
Elements paragraphs = document.getElementsByTag("p");
StringBuffer plainText = new StringBuffer(html.length() / 2);
for (int i = 0; i < paragraphs.size(); i++) {
Element paragraph = paragraphs.get(i);
plainText.append(paragraph.text()).append("\n");
}
page.setPlainText(plainText.toString());
return page;
}
}
代码不超过40行,非常简单,现在可以直接返回Page对象了,写一个测试类,来测试这个PageResponseHandler.测试这个类的功能也不需要复杂的代码。
public class PageResponseHandlerTest {
HttpClient httpclient;
PageResponseHandler pageResponseHandler;
final String url = "http://news.163.com/13/0903/11 ... 3B%3B
Page page = new Page(url);
@Before
public void setUp() throws Exception {
httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet(url);
pageResponseHandler = new PageResponseHandler(page);
httpclient.execute(httpget, pageResponseHandler);
}
@After
public void tearDown() throws Exception {
httpclient.getConnectionManager().shutdown();
}
@Test
public void test() {
System.out.println(page.getPlainText());
assertTrue(page.getPlainText().length() > 0);
assertTrue(page.getAnchors().size() > 0);
}
}
到目前为止,这个爬虫中的抓取和分析功能部分都工作的很好,对于中文,也能很好的解析,比较细心的读者会看到,这些代码中并没有设置字符集,也没有进行字符集进行转换,稍后会讲到HttpClient 4.2组件中字符集的处理。
先回顾一下关于HTTP协议的RFC规范中Content-Type作用,它指明发送给接收者Http Entity内容的媒介类型,对于文本类型的HttpEntity而言,它通常是下面的形式,指定HttpEntity的媒介类型,使用了何种字符集进行编码的,此外RFC规范还规定了,在Content-Type没有指定字符集的情况,默认使用ISO-8859-1字符集对Http Entity进行编码
1
Content-Type: text/html; charset=UTF-8
说到这里,大家应该能猜到HttpClient 4.2是如何能正确的进行编码的----就是利用Content-Type头中所收录的字符集作为编码的输入源。具体的代码可以看EntityUtils这个类的第212行开始的代码。EntityUtils首先从HttpEntity对象中获取Content-Type, 如果Content-Type的字符集不为空,则使用Content-Type对象中指定的字符集进行编码,否则使用开发者指定的字符集进行编码,如果开发者也没有指定字符集,使用默认的字符集iso-8859-1进行编码,当然编码实现,还是调用JDK的Reader类。
ContentType contentType = ContentType.getOrDefault(entity);
Charset charset = contentType.getCharset();
if (charset == null) {
charset = defaultCharset;
}
if (charset == null) {