从头学习爬虫(十五)重构篇----爬虫架构

本文主要介绍下爬虫架构部分。

本人渣渣,初学或者到现在有时候为了偷懒,不喜欢用框架。

初设想

单机模式

1 深度问题 通过 主页 -列表页 -详情页 -

2 多线程问题 基本只在详情页 去做线程管理

3 在想要那层做数据持久化操作

遇到问题

1 重复url 处理 通过数据库去去重 效率低。

2 线程池管理混乱异常处理。

3 没有可扩展性,比如多一层代码就要多加一层。

4 失败url 不宜重新爬取。

优点

1 代码简明

2 容易排查异常

3 适用于日常所需

框架介绍

今天我们主要探寻下一款爬虫框架webmagic


初学者很容易理解,可以想成一个循环通过中间process 去处理 downloader 返回request经过处理请求信息page对象

根据你所需要的信息进行数据持久化。

详细可以点击打开链接,请仔细阅读文档,源码解析我们会在后面进行,时间可能会隔得比较久。

实战

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.util.HashSet;
import java.util.Set;

import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.Spider;
import us.codecraft.webmagic.processor.PageProcessor;
import us.codecraft.webmagic.scheduler.PriorityScheduler;

public class Wall implements PageProcessor{
	//存储过滤url
	public static Set<String> set=new HashSet();
        //列表页
	public static final String URL_LIST = "by_sub_category\\.php\\?id=226985&name=%E4%B8%9C%E4%BA%AC%E9%A3%9F%E5%B0%B8%E9%AC%BC\\+%E5%A3%81%E7%BA%B8&lang=Chinese&page=\\d+";
	//详情页
	public static final String URL_POST = "https://wall\\.alphacoders\\.com/big.php\\?i=\\d{6}&lang=Chinese";
        //原图
	public static final String IMAGE = "https://images3\\.alphacoders\\.com/\\d{3}/\\d{6}\\.png";
    
    private Site site = new Site().me()
            .setRetryTimes(3).setTimeOut(5000000).setSleepTime(100)
    		.addHeader("User-Agent","Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.80 Safari/537.36 Core/1.47.516.400 QQBrowser/9.4.8188.400");
    @Override
    public void process(Page page) {
    	//加入列表页
    	page.addTargetRequests(page.getHtml().links().regex(URL_LIST).all());
    	
        if (page.getUrl().regex(URL_LIST).match()) {
            //如果是列表页 我们从页面中正则匹配详情页
        	page.addTargetRequests(page.getHtml().links().regex(URL_POST).all());
         
        } else {
        	//如果是详情页或者主页(这边代码有问题不应该加上主页),找到对应原图url,本意是打算用image去过滤的。加到set过滤重复url
        	set.add(page.getHtml().xpath("//div[@style='width:100%;padding:10px;max-width:975px;margin:auto;']/div[@class='row']/div/span/@data-href").toString());
        
        }
    }
    @Override
    public Site getSite() {
        return site;
    }

    public static void main(String[] args) throws Exception {
    	
        Spider.create(new Wall()).addUrl("https://wall.alphacoders.com/by_sub_category.php?id=226985&name=%E4%B8%9C%E4%BA%AC%E9%A3%9F%E5%B0%B8%E9%AC%BC+%E5%A3%81%E7%BA%B8&lang=Chinese").thread(5)
                .run();
        FileOutputStream fos=new FileOutputStream(new File("E:/DONGJING.txt"));
        OutputStreamWriter osw=new OutputStreamWriter(fos, "UTF-8");
        BufferedWriter  bw=new BufferedWriter(osw);
        
        for(String string : set){
            //存储方法
        }
        
        //注意关闭的先后顺序,先打开的后关闭,后打开的先关闭
        bw.close();
        osw.close();
        fos.close();
       
    }
}

对照官网写的demo 从wall这个图站去下东京吃货的壁纸。

我还是不习惯pipeline,这几个组件,对于一个入门菜鸟,更关心如何迅速上手。

当初比较简单,都没有问题。

讲下启动过程加入process ,开了5个线程,却使用同步启动方式,线程白写。

由于我自己测试有时候会超时,所以超时时间时间设置的比较长,每个线程做完,休息100ms,失败重试3次。

header 加个UA表示浏览器。

最后有个致命问题,为了过滤我选择加入set。如果url过多很可能内存溢出。

真不如直接直接处理掉,以后也不会这么写,可能会重复。

所以整个程序要解决的是批量过滤数据持久化。



欢迎加群313557283(刚创建),小白互相学习~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值