成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

只聽(tīng)說(shuō)過(guò)用Python做爬蟲(chóng),Java程序員笑了!

開(kāi)發(fā) 后端
網(wǎng)絡(luò)爬蟲(chóng)技術(shù),早在萬(wàn)維網(wǎng)誕生的時(shí)候,就已經(jīng)出現(xiàn)了,今天我們就一起來(lái)揭開(kāi)它神秘的面紗!

[[345062]]

本文轉(zhuǎn)載自微信公眾號(hào)「Java極客技術(shù)」,作者鴨血粉絲 。轉(zhuǎn)載本文請(qǐng)聯(lián)系Java極客技術(shù)公眾號(hào)。  

網(wǎng)絡(luò)爬蟲(chóng)技術(shù),早在萬(wàn)維網(wǎng)誕生的時(shí)候,就已經(jīng)出現(xiàn)了,今天我們就一起來(lái)揭開(kāi)它神秘的面紗!

一、摘要

說(shuō)起網(wǎng)絡(luò)爬蟲(chóng),相信大家都不陌生,又俗稱網(wǎng)絡(luò)機(jī)器人,指的是程序按照一定的規(guī)則,從互聯(lián)網(wǎng)上抓取網(wǎng)頁(yè),然后從中獲取有價(jià)值的數(shù)據(jù),隨便在網(wǎng)上搜索一下,排在前面基本都是 pyhton 教程介紹。

的確,pyhton 在處理網(wǎng)頁(yè)方面,有著開(kāi)發(fā)簡(jiǎn)單、便捷、性能高效的優(yōu)勢(shì)!

但是我們 java 也不賴,在處理復(fù)雜的網(wǎng)頁(yè)方面,需要解析網(wǎng)頁(yè)內(nèi)容生成結(jié)構(gòu)化數(shù)據(jù)或者對(duì)網(wǎng)頁(yè)內(nèi)容精細(xì)的解析時(shí),java 可以說(shuō)更勝一籌!

下面我們以爬取國(guó)家省市區(qū)信息為例,使用 java 技術(shù)來(lái)實(shí)現(xiàn),過(guò)程主要分三部:

  • 第一步:目標(biāo)網(wǎng)頁(yè)分析
  • 第二步:編寫爬蟲(chóng)程序,對(duì)關(guān)鍵數(shù)據(jù)進(jìn)行抓取
  • 第三步:將抓取的數(shù)據(jù)寫入數(shù)據(jù)庫(kù)

廢話不多說(shuō),直接開(kāi)擼!

二、網(wǎng)頁(yè)分析

網(wǎng)絡(luò)爬蟲(chóng),其實(shí)不是一個(gè)很難的技術(shù),只是需要掌握的技術(shù)內(nèi)容比較多,只會(huì) java 技術(shù)是遠(yuǎn)遠(yuǎn)不夠,還需要熟悉 html 頁(yè)面屬性!

以爬取國(guó)家省市區(qū)信息為例,我們可以直接在百度上搜索國(guó)家省市區(qū),點(diǎn)擊進(jìn)入全國(guó)行政區(qū)劃信息查詢平臺(tái)。

在民政數(shù)據(jù)菜單欄下,找到最新的行政區(qū)域代碼公示欄。

點(diǎn)擊進(jìn)去,展示結(jié)果如下!

可以很清楚的看到,這就是我們要獲取省市區(qū)代碼的網(wǎng)頁(yè)信息。

可能有的同學(xué)會(huì)問(wèn),這么直接干合不合法?

國(guó)家既然已經(jīng)公示了,我們直接拿來(lái)用就可以,完全合法!而且國(guó)家省市區(qū)代碼是一個(gè)公共字典,在很多業(yè)務(wù)場(chǎng)景下必不可少!

當(dāng)我們找到了目標(biāo)網(wǎng)頁(yè)之后,我們首先要做的就是對(duì)網(wǎng)頁(yè)進(jìn)行分析,打開(kāi)瀏覽器調(diào)試器,可以很清晰的看到它是一個(gè)table表格組成的數(shù)據(jù)。

熟悉 html 標(biāo)簽的同學(xué),想必已經(jīng)知道了它的組成原理。

其實(shí)table是一個(gè)非常簡(jiǎn)單的 html 標(biāo)簽,主要有tr和td組成,其中tr代表行,td代表列,例如用table標(biāo)簽畫一個(gè)學(xué)生表格,代碼如下:

  1. <table
  2.  <!-- 定義表格頭部 --> 
  3.  <tr> 
  4.   <td>編號(hào)</td> 
  5.   <td>姓名</td> 
  6.  </tr> 
  7.  <!-- 定義表格內(nèi)容 --> 
  8.  <tr> 
  9.   <td>100</td> 
  10.   <td>張三</td> 
  11.  </tr> 
  12.  <tr> 
  13.   <td>101</td> 
  14.   <td>李四</td> 
  15.  </tr> 
  16. </table

 展示結(jié)果如下:

了解了table標(biāo)簽之后,我們?cè)賹?duì)網(wǎng)頁(yè)進(jìn)行詳細(xì)分析。

首先對(duì)整個(gè)內(nèi)容進(jìn)行觀察,很容易的看到,市級(jí)以上(包括市級(jí)),都是黑體字加粗的,區(qū)或者縣級(jí)地區(qū),都是常規(guī)!

出現(xiàn)這個(gè)現(xiàn)象,其實(shí)是由樣式標(biāo)簽CSS來(lái)控制的,點(diǎn)擊北京市,找到對(duì)應(yīng)的代碼位置,從圖中我們可以很清晰的看到,市級(jí)對(duì)應(yīng)的樣式class為xl7030796,區(qū)或者縣級(jí)地區(qū)對(duì)應(yīng)的樣式class為xl7130796

除此之外,我們繼續(xù)來(lái)看看省和市級(jí)的區(qū)別!

可以很清晰的看到,市級(jí)相比省級(jí)信息,多了一個(gè)span占位符標(biāo)簽。

于是,我們可以得出如下結(jié)論:

省級(jí)信息,樣式標(biāo)簽為xl7030796

市級(jí)信息,樣式標(biāo)簽為xl7030796,同時(shí)包含span占位符標(biāo)簽

區(qū)或者縣級(jí)信息,樣式標(biāo)簽為xl7130796

等會(huì)會(huì)通過(guò)這些規(guī)律信息來(lái)從網(wǎng)頁(yè)信息中抓取省、市、區(qū)信息。

三、編寫爬蟲(chóng)程序

3.1、創(chuàng)建項(xiàng)目

新建一個(gè)基于 maven 工程 java 項(xiàng)目,在pom.xml工程中引入如下 jar 包!

  1. <!--解析HTML--> 
  2. <dependency> 
  3.     <groupId>org.jsoup</groupId> 
  4.     <artifactId>jsoup</artifactId> 
  5.     <version>1.11.2</version> 
  6. </dependency> 

3.2、編寫爬取程序

先創(chuàng)建一個(gè)實(shí)體數(shù)據(jù)類,用于存放抓取的數(shù)據(jù)

  1. public class ChinaRegionsInfo { 
  2.  
  3.     /** 
  4.      * 行政區(qū)域編碼 
  5.      */ 
  6.     private String code; 
  7.  
  8.     /** 
  9.      * 行政區(qū)域名稱 
  10.      */ 
  11.     private String name
  12.  
  13.     /** 
  14.      * 行政區(qū)域類型,1:省份,2:城市,3:區(qū)或者縣城 
  15.      */ 
  16.     private Integer type; 
  17.  
  18.     /** 
  19.      * 上一級(jí)行政區(qū)域編碼 
  20.      */ 
  21.     private String parentCode; 
  22.  
  23.     //省略get、set 

然后,我們來(lái)編寫爬取代碼,將抓取的數(shù)據(jù)封裝到實(shí)體類中

  1. //需要抓取的網(wǎng)頁(yè)地址 
  2. private static final String URL = "http://www.mca.gov.cn//article/sj/xzqh/2020/202006/202008310601.shtml"
  3.  
  4. public static void main(String[] args) throws IOException { 
  5.     List<ChinaRegionsInfo> regionsInfoList = new ArrayList<>(); 
  6.  //抓取網(wǎng)頁(yè)信息 
  7.     Document document = Jsoup.connect(URL).get(); 
  8.  //獲取真實(shí)的數(shù)據(jù)體 
  9.     Element element = document.getElementsByTag("tbody").get(0); 
  10.     String provinceCode = "";//省級(jí)編碼 
  11.     String cityCode = "";//市級(jí)編碼 
  12.     if(Objects.nonNull(element)){ 
  13.         Elements trs = element.getElementsByTag("tr"); 
  14.         for (int i = 3; i < trs.size(); i++) { 
  15.             Elements tds = trs.get(i).getElementsByTag("td"); 
  16.             if(tds.size() < 3){ 
  17.                 continue
  18.             } 
  19.             Element td1 = tds.get(1);//行政區(qū)域編碼 
  20.             Element td2 = tds.get(2);//行政區(qū)域名稱 
  21.             if(StringUtils.isNotEmpty(td1.text())){ 
  22.                 if(td1.classNames().contains("xl7030796")){ 
  23.                     if(td2.toString().contains("span")){ 
  24.                         //市級(jí) 
  25.                         ChinaRegionsInfo chinaRegions = new ChinaRegionsInfo(); 
  26.                         chinaRegions.setCode(td1.text()); 
  27.                         chinaRegions.setName(td2.text()); 
  28.                         chinaRegions.setType(2); 
  29.                         chinaRegions.setParentCode(provinceCode); 
  30.                         regionsInfoList.add(chinaRegions); 
  31.                         cityCode = td1.text(); 
  32.                     } else { 
  33.                         //省級(jí) 
  34.                         ChinaRegionsInfo chinaRegions = new ChinaRegionsInfo(); 
  35.                         chinaRegions.setCode(td1.text()); 
  36.                         chinaRegions.setName(td2.text()); 
  37.                         chinaRegions.setType(1); 
  38.                         chinaRegions.setParentCode(""); 
  39.                         regionsInfoList.add(chinaRegions); 
  40.                         provinceCode = td1.text(); 
  41.                     } 
  42.  
  43.                 } else { 
  44.                     //區(qū)或者縣級(jí) 
  45.                     ChinaRegionsInfo chinaRegions = new ChinaRegionsInfo(); 
  46.                     chinaRegions.setCode(td1.text()); 
  47.                     chinaRegions.setName(td2.text()); 
  48.                     chinaRegions.setType(3); 
  49.                     chinaRegions.setParentCode(StringUtils.isNotEmpty(cityCode) ? cityCode : provinceCode); 
  50.                     regionsInfoList.add(chinaRegions); 
  51.                 } 
  52.             } 
  53.         } 
  54.     } 
  55.     //打印結(jié)果 
  56.     System.out.println(JSONArray.toJSONString(regionsInfoList)); 

運(yùn)行程序,輸出結(jié)果如下:

json解析結(jié)果如下:

至此,網(wǎng)頁(yè)有效數(shù)據(jù)已經(jīng)全部抓取完畢!

四、寫入數(shù)據(jù)庫(kù)

在實(shí)際的業(yè)務(wù)場(chǎng)景中,我們需要做的不僅僅只是抓取出有價(jià)值的數(shù)據(jù),最重要的是將這些數(shù)據(jù)記錄數(shù)據(jù)庫(kù),以備后續(xù)的業(yè)務(wù)可以用的上!

例如,當(dāng)我們?cè)陂_(kāi)發(fā)一個(gè)給員工發(fā)放薪資系統(tǒng)的時(shí)候,其中的社保、公積金,可能每個(gè)城市都不一樣,這個(gè)時(shí)候就會(huì)到國(guó)家省市區(qū)編碼。

因此,我們可以將抓取的國(guó)家省市區(qū)編碼寫入數(shù)據(jù)庫(kù)!

在上面,我們已經(jīng)將具體的省市區(qū)數(shù)據(jù)結(jié)構(gòu)封裝成數(shù)組對(duì)象,寫入過(guò)程也很簡(jiǎn)單。

首先,創(chuàng)建一張國(guó)家行政地域信息表china_regions

  1. CREATE TABLE `china_regions` ( 
  2.   `id` bigint(20) unsigned NOT NULL COMMENT '主鍵ID'
  3.   `code` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '行政地域編碼'
  4.   `namevarchar(50) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '行政地域名稱'
  5.   `type` tinyint(4) NOT NULL DEFAULT '1' COMMENT '行政地域類型,1:省份,2:城市,3:區(qū)域'
  6.   `parent_code` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '上一級(jí)行政編碼'
  7.   `is_delete` tinyint(4) NOT NULL DEFAULT '0' COMMENT '是否刪除 1:已刪除;0:未刪除'
  8.   `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '創(chuàng)建時(shí)間'
  9.   `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新時(shí)間'
  10.   PRIMARY KEY (`id`), 
  11.   KEY `idx_code` (`code`) USING BTREE, 
  12.   KEY `idx_name` (`name`) USING BTREE, 
  13.   KEY `idx_type` (`type`) USING BTREE, 
  14.   KEY `idx_parent_code` (`parent_code`) USING BTREE 
  15. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='國(guó)家行政地域信息表'

搭建一個(gè)springboot工程,通過(guò)mybatis-plus組件,一鍵生成代碼

最后,配置好數(shù)據(jù)源,重新封裝數(shù)組對(duì)象,調(diào)用批量插入方法,即可插入操作

  1. chinaRegionsService.saveBatch(regionsInfoList); 

插入執(zhí)行完之后,數(shù)據(jù)庫(kù)結(jié)果如下

至此,大部分工作基本已經(jīng)完成!

但是,細(xì)心的你,可能會(huì)發(fā)現(xiàn)還有數(shù)據(jù)問(wèn)題,因?yàn)槲覀儑?guó)家在省級(jí)區(qū)域上,還有一個(gè)直轄市的概念,以北京市為例,在數(shù)據(jù)庫(kù)中type類型為1,表示省級(jí)類型,但是它的子級(jí)是一個(gè)區(qū),中間還掉了一層市級(jí)類型。

因此,我們還需要對(duì)這些直轄市類型的數(shù)據(jù)進(jìn)行修復(fù),查詢出所有的直轄市類型的城市。

對(duì)這些編號(hào)的城市,單獨(dú)處理,中間加一層市級(jí)類型!

至此,國(guó)家省市區(qū)編碼數(shù)據(jù)字典,全部處理完畢!

五、總結(jié)

本篇主要以爬取國(guó)家省市區(qū)編號(hào)為例,以 java 技術(shù)為背景進(jìn)行講解,在整個(gè)爬取過(guò)程中,最重要的一部分就是網(wǎng)頁(yè)分析,找出規(guī)律,然后通過(guò)jsoup工具包解析網(wǎng)頁(yè),獲取其中的有效數(shù)據(jù)。

同時(shí),技術(shù)是一把雙面刀,希望同學(xué)們能正當(dāng)使用!

七、參考

1、2020年行政區(qū)劃代碼

2、jsoup -中文文檔

 

責(zé)任編輯:武曉燕 來(lái)源: Java極客技術(shù)
相關(guān)推薦

2023-11-10 08:22:09

雪花算法生成算法分布式

2022-03-21 11:50:58

醫(yī)療物聯(lián)網(wǎng)物聯(lián)網(wǎng)

2021-10-18 21:41:10

Go程序員 Defer

2022-05-09 08:40:14

Python技巧代碼

2020-11-16 12:09:25

Python開(kāi)發(fā)工具

2016-01-27 10:26:53

JavaScript操作系統(tǒng)

2012-02-01 10:18:23

編程

2016-07-11 00:40:30

2022-12-09 14:31:24

程序員編程

2020-03-02 09:06:29

口頭禪不配程序員

2018-10-11 10:41:12

Go 開(kāi)發(fā)技術(shù)

2016-01-26 15:33:07

JavaScriptNodeOS操作系統(tǒng)

2018-09-28 07:00:03

編程語(yǔ)言Go語(yǔ)言

2024-05-24 10:15:36

2022-09-29 08:39:37

架構(gòu)

2023-07-13 09:16:47

循環(huán)隊(duì)列指針front?

2018-11-01 15:20:17

前端程序員編程語(yǔ)言

2020-09-14 08:47:46

緩存程序員存儲(chǔ)

2021-06-07 09:55:58

JavaScript開(kāi)發(fā) 技巧

2017-08-30 12:17:02

Python王者榮耀套路
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 91网站在线看 | 国产日韩欧美一区二区 | 欧美综合在线观看 | 九九九精品视频 | 天堂va在线 | 91精品国产综合久久福利软件 | 欧美一区二区三区 | 国产福利在线视频 | 亚洲一区 中文字幕 | 亚洲国产欧美一区 | 国产在线视频在线观看 | 99热激情| 久久成人精品视频 | 精品一级| 欧美v免费| 91久久网站 | 一区二区三区av | 欧美黄色一区 | 色综合99 | 欧美综合精品 | 91在线影院| 亚洲精品一区二区三区在线 | 欧美www在线观看 | 久久久资源 | 亚洲精品大片 | 日韩成人在线播放 | 亚洲一区国产 | 国产欧美日韩一区二区三区在线 | 亚洲视频一区 | 久久久久亚洲 | 久久精品国产99国产精品 | 欧美视频中文字幕 | www.国产| 亚洲国产精品一区二区第一页 | 久久久久久国产精品免费免费 | 亚洲一区亚洲二区 | 日韩亚洲一区二区 | 国产视频一区二区 | 色婷婷在线视频 | 91视频网址| 久久久精品视频一区二区三区 |