1、1个主线程+1个列表线程+N个明细线程
对要爬取的网站数据,基本是采用分页的形式展现,通过遍历列表解析明细URL,进而爬取明细页面内容;
每个网站一个处理线程,爬取列表和爬取明细采用单独的子线程,列表爬取线程相当于生成者,分页一般在几十条,有些网站可在请求中指定分页大小参数可达百条一页,生产速度足够消费,单线程爬取解析列表,往无界阻塞队列存待爬的明细url,根据带宽(避免IO超时)和服务器性能(500响应码)配置N个明细爬取线程作为消费者,对爬取内容进行解析,缓存解析后实体对象,达到一定量时批量持久化。列表单线程生产速度可控,看过几个开源框架列表和明细的url是在同一个队列,那就会有优先级问题,队列中同时有列表和明细时需要明细先爬,未区分列表和明细,每个线程既处理列表又处理明细,何时停止爬取是个麻烦问题,队列中没有可用url并不代表爬完,可能有某个线程还在爬一个列表呢。
2、爬完一个网站需要记录爬取情况日志信息,比如新增记录数、修改记录数、服务端异常次数(异常太多可减少明细线程数)、IO异常次数(异常太多可减少明细线程数)、开始时间、结束时间、异常信息等;
3、多个网站同时爬取时在外面套一层,3层线程结构,第一层里启动各源线程,第二层里启动列表和明细;
run() { for(int i=0;i<x;i++)new Thread(new PullXXX()).start(); } AbstractPull implements Runnable { PullList implements Runnable{}; PullDetail implements Runnable{}; run() { new Thread(new PullList()).start(); for(int i=0;i<N;i++) { new Thread(new PullDetail()).start(); } CountDownLatch.await(); log(); } }
时间: 2024-10-13 06:11:43