使用WebMagic快速配置你的“小虫子”

前言

距上一次发博已经有一个月的时间了,期间一直在优化某功能模块,每次都搞到很晚才回家。所以就没有新的内容发布。
国庆之后我负责了几个爬虫,主要就是自己编写爬虫抓取BAT三家公司的职位信息,还有就是三大人才网的职位信息,这三个之前用了webmagic写的,我就负责维护,总体来说还算是轻松的,就是最后一个猎聘网,需要用代理ip来抓取,花了点时间在网上找了个比较不错的代理ip站点,下面就把webmagic的使用过程抽了出来,方便下一次的快速使用。

webmagic简介

http://webmagic.io/docs/zh/ 这是官方的中文说明,很详细我就不再做过多的解释了,只想提醒几点:

  • 适合大部分的列表-内容网站,如CSDN博文列表与对应内容等类似格式额网站
  • 要会一些简单的正则表达式与xpath(如果不会的话,使用chrom的插件xpath也是一个不错的选择)
  • 不要过分的依赖此框架

简单的配置抓取智联招聘的职位信息

编写一个model并使用@ExtractBy注解编写xpath语法来为每个属性赋值

@TargetUrl({"http://jobs.zhaopin.com/*.htm?*"})
@HelpUrl({"http://sou.zhaopin.com/jobs/searchresult.ashx?*"})
public class ZhilianJobInfo
        implements AfterExtractor {

    @ExtractBy("//h1/text()")
    private String title = "";

    @ExtractBy("//html/body/div[6]/div[1]/ul/li[1]/strong/text()")
    private String salary = "";

    @ExtractBy("//html/body/div[5]/div[1]/div[1]/h2/a/text()")
    private String company = "";

    @ExtractBy("//html/body/div[6]/div[1]/div[1]/div/div[1]/allText()")
    private String description = "";

    private String source = "zhilian.com";

    @ExtractByUrl
    private String url = "";

    private String urlMd5 = "";

    @ExtractBy("//html/body/div[6]/div[1]/ul/li[2]/strong/a/text()")
    private String dizhi = "";

    @ExtractBy("//html/body/div[6]/div[1]/ul/li[5]/strong/text()")
    private String qualifications = "";

    @ExtractBy("//html/body/div[6]/div[2]/div[1]/ul/li[3]/strong/a/text()")
    private String companycategory = "";

    @ExtractBy("//html/body/div[6]/div[2]/div[1]/ul/li[1]/strong/text()")
    private String companyscale = "";

    @ExtractBy("//html/body/div[6]/div[2]/div[1]/ul/li[2]/strong/text()")
    private String companytype = "";

    @ExtractBy("//html/body/div[6]/div[2]/div[1]/ul/li[4]/strong/text()")
    private String companyaddress;

    public String getTitle() {
        return this.title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getCompany() {
        return this.company;
    }

    public void setCompany(String company) {
        this.company = company;
    }

    public String getDescription() {
        return this.description;
    }

    public void setDescription(String description) {
        if (description != null)
            this.description = description;
    }

    public String getSource() {
        return this.source;
    }

    public void setSource(String source) {
        this.source = source;
    }

    public String getUrl() {
        return this.url;
    }

    public void setUrl(String url) {
        this.url = url;
        this.urlMd5 = DigestUtils.md5Hex(url);
    }

    public String getSalary() {
        return this.salary;
    }

    public void setSalary(String salary) {
        this.salary = salary;
    }

    public String getUrlMd5() {
        return this.urlMd5;
    }

    public void setUrlMd5(String urlMd5) {
        this.urlMd5 = urlMd5;
    }

    public String getDizhi() {
        return this.dizhi;
    }

    public void setDizhi(String dizhi) {
        this.dizhi = dizhi;
    }

    public String getQualifications() {
        return this.qualifications;
    }

    public void setQualifications(String qualifications) {
        this.qualifications = qualifications;
    }

    public String getCompanycategory() {
        return this.companycategory;
    }

    public void setCompanycategory(String companycategory) {
        this.companycategory = companycategory;
    }

    public String getCompanyscale() {
        return this.companyscale;
    }

    public void setCompanyscale(String companyscale) {
        this.companyscale = companyscale;
    }

    public String getCompanytype() {
        return this.companytype;
    }

    public void setCompanytype(String companytype) {
        this.companytype = companytype;
    }

    public String getCompanyaddress() {
        return this.companyaddress;
    }

    public void setCompanyaddress(String companyaddress) {
        this.companyaddress = companyaddress;
    }

    public String toString() {
        return "JobInfo{title='" + this.title + '\'' + ", salary='" + this.salary + '\'' + ", company='" + this.company + '\'' + ", description='" + this.description + '\'' + ", source='" + this.source + '\'' + ", url='" + this.url + '\'' + '}';
    }

    public void afterProcess(Page page) {
    }
}

再来就是实现Crawler的Pipeline来决定你抓取的数据的存储方式

public class ZhilianModelPipeline implements PageModelPipeline<ZhilianJobInfo> {


    public void process(ZhilianJobInfo zhilianJobInfo, Task task) {
        // save info to db
        System.out.println(zhilianJobInfo);
    }
}

最后就是爬虫的一些配置和启动入口(今天加了IP代理池)

public class Crawler {
    public static void main(String[] args) {
        // IP代理池
        HttpClientDownloader httpClientDownloader = new HttpClientDownloader();
        try {
            List<Proxy> proxies = buildProxyIP();
            System.out.println("请求代理IP: " + proxies);
            httpClientDownloader.setProxyProvider(new SimpleProxyProvider(proxies));
        } catch (IOException e) {
            e.printStackTrace();
        }

        OOSpider.create(Site.me()
                .setSleepTime(5)
                .setRetrySleepTime(10)
                .setCycleRetryTimes(3),
                new ZhilianModelPipeline(),ZhilianJobInfo.class)
                .addUrl("http://sou.zhaopin.com/jobs/searchresult.ashx?jl=765&bj=7002000&sj=463")
                .thread(60)
                .setDownloader(httpClientDownloader)
                .run();
    }


    /**
     * 不错的免费代理IP站点
     * www.89ip.cn
     *
     * @return
     */
    private static List<Proxy> buildProxyIP() throws IOException {
        Document parse = Jsoup.parse(new URL("http://www.89ip.cn/tiqv.php?sxb=&tqsl=50&ports=&ktip=&xl=on&submit=%CC%E1++%C8%A1"), 5000);
        String pattern = "(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+):(\\d+)";
        Pattern r = Pattern.compile(pattern);
        Matcher m = r.matcher(parse.toString());
        List<Proxy> proxies = new ArrayList<Proxy>();
        while (m.find()) {
            String[] group = m.group().split(":");
            int prot = Integer.parseInt(group[1]);
            proxies.add(new Proxy(group[0], prot));
        }
        return proxies;
    }
}

很快就可以抓取了。代码在https://github.com/vector4wang/webmagic-quick

完了,又水了一贴。。。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容

  • 要玩大数据,没有数据怎么玩?这里推荐一些33款开源爬虫软件给大家。 爬虫,即网络爬虫,是一种自动获取网页内容的程序...
    评评分分阅读 7,835评论 2 121
  • scrapy学习笔记(有示例版) 我的博客 scrapy学习笔记1.使用scrapy1.1创建工程1.2创建爬虫模...
    陈思煜阅读 12,587评论 4 46
  • 33款可用来抓数据的开源爬虫软件工具 要玩大数据,没有数据怎么玩?这里推荐一些33款开源爬虫软件给大家。 爬虫,即...
    visiontry阅读 7,087评论 1 99
  • 到此时为止,结束一小段关系,已有48小时之久,像离愁别绪似的,它在人内心里产生化学反应,至少有较长的日子,沉...
    天青81阅读 94评论 0 0
  • 上中学的时候 A是一名老师 他告诉学生 抓到山羊🐐才有羊奶喝 学生B担惊受怕不敢抓山羊🐐 最终抓不到山羊🐐 学生C...
    哦安妮阅读 199评论 4 2