问题导读:
1.了解爬虫编写的基本思路
2.扩充淘淘商城数据数据量
技术:
抓取京东色商品数据
数据保存到数据库中和索引库中
使用线程池进行多线程并发
使用jsoup分析页面
使用httpclient连接池实现http请求管理
Spring+Mybaits+HttpClient+Lucene+Jsoup
编写爬虫分析:
1.指定入口页面
2.根据规则抓取页面数据
3.根据html源码,获取到所需要的内容
4.存储(mysql、索引库)
抓取图片:
$("#J_goodsList li").eq(0).find(".p-img img").eq(1).attr("src");
"//img13.360buyimg.com/n7/jfs/t2593/193/3399807000/138331/3d4afe1b/578c40f1N8418b28a.jpg"
$("#J_goodsList li").eq(0).find(".p-price strong").attr("data-price");
"5499.00"
$("#J_goodsList li").eq(0).find(".p-name a").attr("title");
"联想(Lenovo)拯救者 ISK15.6英寸游戏笔记本电脑(i5-6300HQ 8G 1T HDD GTX960M 4G独显 FHD IPS屏 )黑"
$("#J_goodsList li").eq(0).find(".p-commit strong").text()
"已有4.2万+人评价"
JD查询商品价格的接口:
https://p.3.cn/prices/mgets?skuIds=J_2600210
多个商品返回,中间使用“,”分隔:
https://chat1.jd.com/api/checkChat?pidList=2605210
主代码实现:
package cn.itcast.crawler;
import java.util.Map;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.itcast.crawler.thread.ThreadPool;
public class Main {
public static ApplicationContext applicationContext;
public static void main(String[] args) throws Exception {
applicationContext = new ClassPathXmlApplicationContext("spring/applicationContext*.xml");
//从Spring容器中获取到所有可以执行的爬虫,并且放到线程池中执行
Map<String, Crawler> map = applicationContext.getBeansOfType(Crawler.class);
for (Crawler crawler : map.values()) {
ThreadPool.runInThread(crawler);
}
}
}
ThreadPool
package cn.itcast.crawler.thread;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.ThreadPoolExecutor.AbortPolicy;
import java.util.concurrent.TimeUnit;
import cn.itcast.crawler.Main;
import cn.itcast.crawler.service.PropertieService;
public class ThreadPool {
// 线程池维护线程的最少数量
private static final int COREPOOLSIZE = 2;
// 线程池维护线程的最大数量
private static final int MAXINUMPOOLSIZE = Integer.valueOf(Main.applicationContext.getBean(PropertieService.class).MAX_POOL_SIZE);
// 线程池维护线程所允许的空闲时间
private static final long KEEPALIVETIME = 4;
// 线程池维护线程所允许的空闲时间的单位
private static final TimeUnit UNIT = TimeUnit.SECONDS;
// 线程池所使用的缓冲队列,这里队列大小为3
private static final BlockingQueue<Runnable> WORKQUEUE = new ArrayBlockingQueue<Runnable>(3);
// 线程池对拒绝任务的处理策略:AbortPolicy为抛出异常;CallerRunsPolicy为重试添加当前的任务,他会自动重复调用execute()方法;DiscardOldestPolicy为抛弃旧的任务,DiscardPolicy为抛弃当前的任务
private static final AbortPolicy HANDLER = new ThreadPoolExecutor.AbortPolicy();
private static ThreadPoolExecutor threadPool = new ThreadPoolExecutor(COREPOOLSIZE, MAXINUMPOOLSIZE, KEEPALIVETIME, UNIT, WORKQUEUE, HANDLER);
/**
* 加入到线程池中执行
*
* @param runnable
*/
public static void runInThread(Runnable runnable) {
threadPool.execute(runnable);
}
}
spring中的配置文件:
<!-- 平板电视 --&g