利用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,