最近快618了,各大电商都开始做促销,想必服务器性能很厉害能顶得住亿万级别的访问量。趁这时候我想对某个电商网站进行网络爬虫,爬取一定量的商品数据来做我自己的数据储备。
ps:只做个人数据储备,不对外开放,只用作个人学习使用。
爬虫框架选型
笔者主要是Java开发,也有写过一些python工具,但是python已经很久没写了所以选择Java相关的爬虫框架。
Java网络爬虫框架种类
等等等等,还有很多简单易用的框架。
因为笔者一直使用的是WebMagic,所以这次网络爬虫就选择使用WebMagic这个框架技术。
爬虫代码以及单元测试
总体结构
Downloader
Downloader负责从互联网上下载页面,以便后续处理。WebMagic默认使用了Apache HttpClient作为下载工具。
PageProcessor
PageProcessor负责解析页面,抽取有用信息,以及发现新的链接。WebMagic使用Jsoup作为HTML解析工具,并基于其开发了解析XPath的工具Xsoup。
在这四个组件中,PageProcessor
对于每个站点每个页面都不一样,是需要使用者定制的部分。
Scheduler
Scheduler负责管理待抓取的URL,以及一些去重的工作。WebMagic默认提供了JDK的内存队列来管理URL,并用集合来进行去重。也支持使用Redis进行分布式管理。
除非项目有一些特殊的分布式需求,否则无需自己定制Scheduler。
Pipeline
Pipeline负责抽取结果的处理,包括计算、持久化到文件、数据库等。WebMagic默认提供了“输出到控制台”和“保存到文件”两种结果处理方案。
Pipeline
定义了结果保存的方式,如果你要保存到指定数据库,则需要编写对应的Pipeline。对于一类需求一般只需编写一个Pipeline
。
官方文档对四大组件进行了详细的解析,并且给出了相关的例子,感兴趣可以去看一下。
核心代码
测试爬取的页面
使用api请求工具对要爬取的链接发起请求,查看返回的是json串还是html页面
如果是html页面那就要分析页面进行爬取,如果返回的是json串那比较简单,只须提取特定字段即可。
这里我查找了一些python的商品,好庆幸返回的是json串,这样我只需要抽取特殊字段就可以了。
爬虫代码
依赖
<dependency>
<groupId>us.codecraft</groupId>
<artifactId>webmagic-core</artifactId>
<version>0.7.4</version>
</dependency>
<dependency>
<groupId>us.codecraft</groupId>
<artifactId>webmagic-extension</artifactId>
<version>0.7.4</version>
</dependency>
强烈推荐使用0.7.4或以上的依赖,因为0.7.4以下的包体在爬取https网站的时候会有ssl错误,需要手动改写代码,以下是github的issues
页面解析
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Document(indexName = "goods")
public class shop {
@Id
private String id;
private String ad_title;
private String color;
private String fuzzy_comment_num;
private String link_url;
private String shop_link;
}
@Slf4j
public class webCatch implements PageProcessor {
//设置重试时间和休眠时间
private Site site = Site.me().setRetryTimes(3).setSleepTime(100);
List<shop> shops = new ArrayList<>(10);
/**
* 自定义数据抽取类
* @param page
*/
@Override
public void process(Page page) {
//设置字符集
site.setCharset("utf-8");
String resultJson = page.getJson().toString();
Map map = JSONObject.parseObject(resultJson);
List<shop> userList = JSONObject.parseArray(map.get("291").toString(), shop.class);
for (shop u: userList) {
//对数据分析并且抽取处理相关字段
u.setAd_title(u.getAd_title().replace("<font class=\"skcolor_ljg\">","").replace("</font>",""));
shops.add(u);
}
log.info(shops.toString());
}
@Override
public Site getSite() {
return site;
}
}
爬虫启动类
public static void main(String[] args) {
String keyword="手机";
Spider.create(new webCatch()).addUrl("你的爬虫url")
.thread(1).run();
}
结果
ok,已经成功抽取到结果并且输出到控制台了。
集成elasticsearch
我将爬取到的数据持久化到es,然后再通过es同步到mysql做一个数据储备。
依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
配置以及代码
yml配置
spring:
elasticsearch:
rest:
uris: 你的elasticsearch地址
持久层
public interface shopMapper extends ElasticsearchRepository<shop,String> {
}
业务层
public void saveData(List<shop> data) {
shopMapper.saveAll(data);
}
爬虫Pipeline处理类
@Slf4j
@Component
public class DetailPipeline implements Pipeline {
@Autowired
private shopService shopService;
@Override
public void process(ResultItems resultItems, Task task) {
List<shop> shopList = resultItems.get("result");
for (shop s:shopList ) {
log.info(s.getShop_link());
log.info(s.getAd_title());
log.info(s.getColor());
log.info(s.getLink_url());
log.info(s.getFuzzy_comment_num());
}
shopService.saveData(shopList);
}
}
启动类改造
@Autowired
DetailPipeline DetailPipeline;
@Test
void getWebMagci() throws InterruptedException {
String keyword="手机";
int page=1;
for (int i = page; i <=5; i++) {
Spider.create(new webCatch()).addUrl("url地址")
//添加自定义处理类
.addPipeline(this.DetailPipeline)
.addPipeline(new FilePipeline("D:\webmagic"))//保存爬取的网页到本地以便后续操作
.addPipeline(new JsonFilePipeline("D:\webmagic\json"))//保存json文件
.thread(1)//开启多少条线程,注意别太多
.run();
page++;
Thread.sleep(1000);//线程休眠,让服务器缓缓
}
}
测试结果
kibana数据可视化
可视化
进入kibana管理页面,并且点击侧栏进入Discover
进入Discover
选择相关的索引后即可看到命中的数据。
关联索引
如果你是第一次使用kibana,请按照以下步骤关联索引
- 点击侧栏底部的Stack Management
- 点击索引模式
- 点击右上角创建索引模式
- 填写es的索引名匹配源
ok,fine! 到这里就基本大功告成了,剩下的就是启动一个定时任务就可以进行爬取数据了。
总结以及注意事项
PS:再次声明,此数据仅为个人学习使用,绝不对外公开
难点
对页面的分析以及抽取是难点,每个人爬取的网站与需求都不一样,要看具体业务需求而定,耐心很重要,多尝试观察返回的结果规则。
如果返回的是json串那就很简单了,如果是返回html页面,则必须对页面进行分析,使用Selectable进行过滤与抽取。
具体抽取方法请查看WebMagic官方文档
注意事项
注意爬虫的线程以及休眠,不要过分请求服务器以免把服务器搞崩,爬取到的数据切勿倒卖,如触犯法律均与作者无关。请勿使用网络爬虫进行违法犯罪活动!!!!