1. 程式人生 > >利用webmagic爬去招聘資訊,並輸入到Hbase資料庫中

利用webmagic爬去招聘資訊,並輸入到Hbase資料庫中

這是一個典型的列表頁+詳情頁情景,而web magic就是對這樣的情況非常適合。讓我們們說一下什麼是web magic它是模仿python 的scrapy,特點主要有
●完全模組化的設計,強大的可擴充套件性。
●核心簡單但是涵蓋爬蟲的全部流程,靈活而強大,也是學習爬蟲入門的好材料。
●提供豐富的抽取頁面API。
●無配置,但是可通過POJO+註解形式實現一個爬蟲。
●支援多執行緒。
●支援分散式。
●支援爬取js動態渲染的頁面。
●無框架依賴,可以靈活的嵌入到專案中去。
對我這種小白來說,是最好的入門的。
它的官方文件地址http://webmagic.io/docs/zh/

2. 好了該檢視我們要爬到資料是

這裡寫圖片描述
用一個user類進行封裝

package linyirencaiwang;

public class User {
    private String key;//keyword
    private String name;//使用者名稱
    private String sex;//性別
    private String minzu;//民族
    private String location;//所在地
    private String identity;//身份學歷
    private String school;//學校
    private String major;//專業
private String work_experience;//工作經驗 private String hope_position;//希望求職崗位 private String hope_palce;//希望工作地點 private String hope_salary;//希望待遇 private String work_type;//希望工作型別 public String getMinzu() { return minzu; } public void setMinzu(String minzu) { this
.minzu = minzu; } public String getWork_experience() { return work_experience; } public void setWork_experience(String work_experience) { this.work_experience = work_experience; } public String getHope_position() { return hope_position; } public void setHope_position(String hope_position) { this.hope_position = hope_position; } public String getHope_palce() { return hope_palce; } public void setHope_palce(String hope_palce) { this.hope_palce = hope_palce; } public String getHope_salary() { return hope_salary; } public void setHope_salary(String hope_salary) { this.hope_salary = hope_salary; } public String getWork_type() { return work_type; } public void setWork_type(String work_type) { this.work_type = work_type; } public String getKey() { return key; } public void setKey(String key) { this.key = key; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getIdentity() { return identity; } public void setIdentity(String identity) { this.identity = identity; } public String getLocation() { return location; } public void setLocation(String location) { this.location = location; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getSchool() { return school; } public void setSchool(String school) { this.school = school; } public String getMajor() { return major; } public void setMajor(String major) { this.major = major; } @Override public String toString() { return "User [name=" + name+ ", sex=" + sex + ", minzu=" + minzu + ", location=" + location+ ", identity=" + identity + ", school=" + school + ", major=" + major + ", work_experience=" + work_experience+ ", hope_position=" +hope_position + ", hope_palce=" + hope_palce + ", hope_salary=" +hope_salary + ", work_type=" +work_type + "]"; } }

3. 接著是爬取資訊類

這裡用於了webmagic框架,只要寫好對應列表頁url和詳細url的正則表示式,webmagic就會進行匹配,就像程式碼裡寫的如果匹配到列表頁的url,就把該頁的詳細頁的url和餘下的列表頁新增到佇列,否則利用xpath獲取詳細頁的資訊。

package linyirencaiwang;
import java.util.ArrayList;
import java.util.List;

import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.Spider;
import us.codecraft.webmagic.pipeline.ConsolePipeline;
import us.codecraft.webmagic.pipeline.FilePipeline;
import us.codecraft.webmagic.processor.PageProcessor;
public class  Test implements PageProcessor {
     private LinyirencaiDao LinyirencaiDao = new LinyircDaoImpL();
     public static final String URL_LIST ="http://rc\\.lyrc\\.net/Companyzp\\.aspx\\?Page=[1-9]{1,3}";
     public static final String URL_POST="/Person_Lookzl/id-[0-9]{4}\\.html";
    // 部分一:抓取網站的相關配置,包括編碼、抓取間隔、重試次數等
     static int size=1;

     private Site site = Site.me().setRetryTimes(3).setSleepTime(1000);
    @Override
    public void process(Page page) {
        // 部分二:定義如何抽取頁面資訊,並儲存下來
        List<String> urls = page.getHtml().css("div#paging").links().regex("/Companyzp\\.aspx\\?Page=").all();
        if(page.getUrl().regex(URL_LIST).match()){

             page.addTargetRequests(page.getHtml().links().regex(URL_POST).all());

             page.addTargetRequests(page.getHtml().links().regex(URL_LIST).all());
             page.addTargetRequests(urls);
        }
        else{
            System.out.println("第"+size+"條");
            size++;
            User user =new User();
            String key="0";//keyword
            String name =page.getHtml().xpath("//*[@width='61%']/table/tbody/tr[1]/td[2]/text()").get();//使用者名稱
            String sex= page.getHtml().xpath("//*[@width='61%']/table/tbody/tr[1]/td[4]/text()").get();//性別
            String minzu=page.getHtml().xpath("//*[@width='61%']/table/tbody/tr[2]/td[4]/text()").get().toString();//民族
            String location= page.getHtml().xpath("//*[@width='61%']/table/tbody/tr[3]/td[4]/text()").get();//所在地
            String identity=page.getHtml().xpath("//*td[@width='283']/text()").get();//身份學歷
            String school=page.getHtml().xpath("//*td[@width='201']/text()").get();//學校
            String major=page.getHtml().xpath("//*[@width='90%']/tbody/tr[2]/td[4]/text()").get();//專業
            String work_experience=page.getHtml().xpath("//td[@width='773']/table/tbody/tr/td/table[6]/tbody/tr[2]/td[2]/text()").get();//工作經驗
            String hope_position=page.getHtml().xpath("//td[@width='773']/table/tbody/tr/td/table[8]/tbody/tr[5]/td[2]/text()").get();//希望求職崗位
            String hope_palce=page.getHtml().xpath("//td[@width='773']/table/tbody/tr/td/table[8]/tbody/tr[4]/td[2]/text()").get();//希望工作地點
            String hope_salary=page.getHtml().xpath("//td[@width='773']/table/tbody/tr/td/table[8]/tbody/tr[2]/td[2]/text()").get();//希望待遇
            String work_type=page.getHtml().xpath("//td[@width='773']/table/tbody/tr/td/table[8]/tbody/tr[1]/td[2]/text()").get();
            user.setHope_palce(name);
            user.setHope_palce(hope_palce);
            user.setHope_position(hope_position);
            user.setHope_salary(hope_salary);
            user.setIdentity(identity); 
            user.setKey(key);
            user.setLocation(location);
            user.setMajor(major);
            user.setMinzu(minzu);
            user.setName(name);
            user.setSchool(school);
            user.setSex(sex);
            user.setWork_experience(work_experience);
            user.setWork_type(work_type);
            System.out.println(user.toString());
            System.out.println();
          LinyirencaiDao.saveUser(user);

        }
        // 部分三:從頁面發現後續的url地址來抓取
    }
    @Override
    public Site getSite() {

        return site;
    }

    public static void main(String args[]) {
        long startTime, endTime;
        startTime =System.currentTimeMillis();
        System.out.println("【爬蟲開始】請耐心等待一大波資料到你碗裡來...");
        Spider.create(new Test()).addUrl("http://rc.lyrc.net/Companyzp.aspx?Page=1")
        //.addPipeline(new FilePipeline("D:\\webmagic\\"))//.addPipeline(new ConsolePipeline)
            .thread(5).run();
        endTime = System.currentTimeMillis();
        System.out.println("【爬蟲結束】共抓取" + size + "篇文章,耗時約" + ((endTime - startTime) / 1000) + "秒,已儲存到資料庫,請查收!");

    }

}

4. 下面是Dao、DaoImpl類

在資料庫中建表和設計列簇。由於這次僅是一個小demo。所以就簡單建一個person2 表,列簇是info,經過我的嘗試,爬取資訊的時間太長,為了執行時間簡短一點,先把名字錄入。

package linyirencaiwang;


public interface LinyirencaiDao {


     public void saveUser(User user);
}
package linyirencaiwang;

import java.io.IOException;


import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;



public class LinyircDaoImpL implements LinyirencaiDao {

    @Override
    public void saveUser(User user)  {
        // TODO Auto-generated method stub
        Configuration conf = HBaseConfiguration.create();
        conf.set("hbase.zookeeper.quorum", "192.168.6.250,192.168.6.251,192.168.6.252");

        try {HBHelper helper = HBHelper.getHelper(conf);
            if(!helper.existsTable("person2")){
                helper.createTable("person2",  "info");
            }
        //  helper.dropTable("person");
        //  helper.createTable("person",  "info");

            helper.insterRow("person2", user.getName(), "info", "name", user.getName());
//           helper.insterRow("person", user.getName(), "info", "sex", user.getSex());
//           helper.insterRow("person", user.getName(), "info", "sex", user.getMinzu());
//           helper.getData("person", "row1","info");
            //helper.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }



}

5. 工具類如下

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellUtil;
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Admin;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import org.apache.hadoop.hbase.client.Get;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.util.Bytes;

public class HBHelper {
    private static Connection connection = null;
      private static Admin admin = null;

      public HBHelper (Configuration conf) {
          try {
              connection = HBHelper.getConnInstance(conf);
            } catch (Exception e) {
                e.printStackTrace();
            }
      } 

      private static synchronized Connection getConnInstance(Configuration conf)throws IOException{
          if(connection==null){
              try{
                  connection = ConnectionFactory.createConnection(conf);
                   admin = connection.getAdmin();
              }
              catch (IOException e) {
            e.printStackTrace();
        } 

        System.out.println("連線資料庫成功");
          }
            return connection;
      }
      public  void close(){  
            try {  
                if(null != admin)  
                    admin.close();  
                if(null != connection)  
                    connection.close();  
                System.out.println("關閉資料庫成功");
            } catch (IOException e) {  
                e.printStackTrace();  
            }  

        }  


      public void createTable(String table, String... colfams)
              throws IOException {
                createTable(table, null, colfams);
              }
      public void createTable(String table, byte[][] splitKeys, String... colfams)
              throws IOException {
                HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(table));
                for (String cf : colfams) {
                  HColumnDescriptor coldef = new HColumnDescriptor(cf);
                  desc.addFamily(coldef);
                }
                if (splitKeys != null) {
                  admin.createTable(desc, splitKeys);
                } else {
                  admin.createTable(desc);
                }
              }

              /**
             * @Title disableTable
             * @Description 禁用table
             * @param table
             * @throws IOException
             */
            public void disableTable(String table) throws IOException {
//              admin.disableTable(table);
                admin.disableTable(TableName.valueOf(table));
              }
            public boolean existsTable(String table)
                      throws IOException {
                        return admin.tableExists(TableName.valueOf(table));
                      }
              /**
             * @Title dropTable
             * @Description dropTable
             * @param table
             * @throws IOException
             */
            public void dropTable(String table) throws IOException {
                if (existsTable(table)) {
                  disableTable(table);
                  admin.deleteTable(TableName.valueOf(table));
                }
              }
            public void insterRow(String tableName,String rowkey,String colFamily,String col,String val) throws IOException {  

                Table table = connection.getTable(TableName.valueOf(tableName));  
                Put put = new Put(Bytes.toBytes(rowkey));  
                put.addColumn(Bytes.toBytes(colFamily), Bytes.toBytes(col), Bytes.toBytes(val));  
                table.put(put);  

                //批量插入  
               /* List<Put> putList = new ArrayList<Put>(); 
                puts.add(put); 
                table.put(putList);*/  
                table.close();  

            }  
              //格式化輸出  
            public  void showCell(Result result){  
                Cell[] cells = result.rawCells(); 

                for(Cell cell:cells){  
                      System.out.println("RowName:"+new String(CellUtil.cloneRow(cell))+", "
                        +"Timetamp:"+cell.getTimestamp()+", "
                        +"column Family:"+new String(CellUtil.cloneFamily(cell))+", "
                        +"列修飾符:"+new String(CellUtil.cloneQualifier(cell))+", "
                        +"value:"+new String(CellUtil.cloneValue(cell))+" ");  
                }  
            }  

            //批量查詢資料  
            public void scanData(String tableName/*,String startRow,String stopRow*/)throws IOException{  

                Table table = connection.getTable(TableName.valueOf(tableName));  
                Scan scan = new Scan();  
                //scan.setStartRow(Bytes.toBytes(startRow));  
                //scan.setStopRow(Bytes.toBytes(stopRow));  
                ResultScanner resultScanner = table.getScanner(scan);  
                for(Result result : resultScanner){  
                    showCell(result);  
                }  
                table.close();  

            }  
            }

6. 整體的框架如圖

這裡寫圖片描述

相關推薦

利用webmagic招聘資訊輸入Hbase資料庫

這是一個典型的列表頁+詳情頁情景,而web magic就是對這樣的情況非常適合。讓我們們說一下什麼是web magic它是模仿python 的scrapy,特點主要有 ●完全模組化的設計,強大的可擴充套件性。 ●核心簡單但是涵蓋爬蟲的全部流程,

【Java爬蟲學習】WebMagic框架爬蟲學習實戰一:取網易雲歌單資訊存入mysql

最近,需要使用Java進行爬蟲編寫,就去學了Java的爬蟲。因為之前學習了Scrapy框架,所以學Java的爬蟲使用了WebMagic框架,這個框架是基於Scrapy框架開發的。大家有興趣可以去看看操作文件:  這個框架是國人開發的,所以說明文件都是中文,簡單易懂。

如何取了知乎使用者資訊做了簡單的分析

爬蟲:python27 +requests+json+bs4+time 分析工具: ELK套件 開發工具:pycharm 1.性別分佈 0 綠色代表的是男性 ^ . ^ 1 代表的是女性 -1 性別不確定 可見知乎的使用者男性頗多。

利用xpath招聘網的招聘資訊

爬取招聘網的招聘資訊: import json import random import time import pymongo import re import pandas as pd import requests from lxml import etree impor

利用Scanner類對檔案讀取獲取相應的資訊

package input; import java.io.File; import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.List; import java.util.Scanner

利用Python實現讀取Nginx日誌將需要信息寫入到數據庫。

creat rip ger form use nginx日誌 zabbix 創建 auth #!/usr/bin/env python # coding: utf-8 # Auther:liangkai # Date:2018/6/26 11:26 # License: (

實戰--Scrapy框架網站資訊

Scrapy的框架圖 一、使用Strapy抓取網站一共需要四個步驟: (1)建立一個Scrapy專案; (2)定義Item容器;  Item是儲存爬取到的資料的容器,其使用方法和python字典類似,並且提供了額外保護機制來i避免拼寫錯誤導致的未定義欄位。

搭建自己的部落格(二十二):通過ajax提交評論資訊增加公式編輯功能

編輯功能使用到了ckeditor的MathJax元件。ajax提交評論可以不用重新整理瀏覽器。 1、變化的部分 2、上程式碼: ul.blog-types,ul.blog-dates { list-style-type: none; } div.blog:no

爬蟲基礎-2-招聘資訊

小生部落格:http://xsboke.blog.51cto.com -------謝謝您的參考,如有疑問,歡迎交流 注意:BOSS應該是做了防爬蟲的功能,好像是如果頻繁訪問,就需要輸入一下驗證碼.為了節省時間,當前只爬取了熱門城市的python相關職位資訊

python 3.x 爬蟲基礎---正則表示式(案例:取貓眼資訊寫入txt,csv,下載圖片)

python 3.x 爬蟲基礎 前言   正則表示式是對字串的一種邏輯公式,用事先定義好的一些特定字元、及這些特定字元的組合,組成一個“規則的字串”,此字串用來表示對字串的一種“過濾”邏輯。正在在很多開發語言中都存在,而非python獨有。對其知識點進行總結後,會寫一個demo。 1.正

Android TV利用viewPager實現輪播圖通過handler進行邏輯控制

    公司要求實現一個輪播圖,滾動圖片及其對應文字。共有五張圖,包含小圓點。     最初的實現是參考了https://blog.csdn.net/zhaoxiaojian1213/article/details/78280132,使用ViewPager實現,新開一個執行

資料庫SQL實戰 —— 查詢employees表所有emp_no為奇數且last_name不為Mary的員工資訊按照hire_date逆序排列

時間限制:1秒 空間限制:32768K 題目描述 查詢employees表所有emp_no為奇數,且last_name不為Mary的員工資訊,並按照hire_date逆序排列 CREATE TABL

Python3 Scrapy框架學習五:使用crawl模板取豆瓣Top250存入MySql、MongoDB

1.新建專案及使用crawl模板 2.頁面解析 rules = (Rule(LinkExtractor(allow=r'subject/\d+/',restrict_css = '.hd > a[class = ""]'), callback='parse_it

獲取12306站點對照資訊保持為json檔案

import time import json import requests from requests.exceptions import RequestException def getResponse(url): try: headers = {'User-Agen

利用Python取房產資料!在地圖上顯示!Python乃蒂花之秀!

    JiwuspiderSpider.py # -*- coding: utf-8 -*- from scrapy import Spider,Request import re from jiwu.items import JiwuItem clas

彙編基礎練習題7:編寫輸入子程式功能是從鍵盤輸入數字字元利用程式得到對應的數值在主程式驗證。

彙編基礎練習題7: 編寫輸入子程式,功能是從鍵盤輸入數字字元,利用程式得到對應的數值,並在主程式中驗證。 編譯工具:Masm for Windows 整合實驗環境2012.5 (附帶一個工具下載地址https://download.csdn.net/download/qq_36931

【Arduino】【ESP】使用Arduino(ESP8266版本)獲取雅虎天氣資訊使用點陣顯示......進行

最近想用Arduino聯網查詢天氣,用點陣顯示。最開始使用2560配合網路模組,後來發現了Esp8266也能當做一個帶有Wifi的arduino板(關鍵是便宜啊!有時間再鼓搗,目前就是刷了ESPEas

php利用phpqrcode生成二維碼將二維碼蓋在一張圖上實現美化

       這兩天在開發一個支付寶授權功能,因為要用到二維碼分享掃描功能,每條記錄都有專屬的二維碼,所以需要生成專屬二維碼並且這個二維碼還得有些引導功能,所以需要將生成的二維碼放在實現準備好的圖片上面。       &nbs

編寫一個手機類(Mobile)包括手機品牌(brand)、手機型號(type) 方法包括顯示手機資訊編寫測試類進行物件的建立

/*編寫一個手機類(Mobile),包括手機品牌(brand)、手機型號(type), * 方法包括顯示手機資訊,並編寫測試類進行物件的建立*/package cyff;public class Mobile {// 定義Mobile類String brand, type

利用c#實現dll動態庫在c++呼叫的方法

           近期,在進行一個大專案開發。其中涉及多語言協同開發。主要是c#dll和c++dll的開發和應用,其中,需要在c++中呼叫c#dll的內容。現在把開發中的經驗、教訓和注意事項總結整理如下,希望對其他人能有所幫助。           1.建立c#dll,