「Python爬蟲系列講解」七、基於數據庫存儲的 BeautifulSoup 招聘爬取

本專欄是以楊秀璋老師爬蟲著作《Python網絡數據爬取及分析「從入門到精通」》爲主線、個人學習理解爲主要內容,以學習筆記形式編寫的。
本專欄不光是自己的一個學習分享,也希望能給您普及一些關於爬蟲的相關知識以及提供一些微不足道的爬蟲思路。
專欄地址:Python網絡數據爬取及分析「從入門到精通」
更多爬蟲實例詳見專欄:Python爬蟲牛刀小試

 前文回顧:
「Python爬蟲系列講解」一、網絡數據爬取概述
「Python爬蟲系列講解」二、Python知識初學 
「Python爬蟲系列講解」三、正則表達式爬蟲之牛刀小試 
「Python爬蟲系列講解」四、BeautifulSoup 技術
「Python爬蟲系列講解」五、用 BeautifulSoup 爬取電影信息
「Python爬蟲系列講解」六、Python 數據庫知識


目錄

1 知識圖譜和招聘網站

2 用 BeautifulSoup 爬取招聘信息

2.1 分析網頁超鏈接及跳轉處理

2.2 DOM 樹節點分析及網頁爬取

3 Navicat for MySQL 工具操作數據庫

3.1 連接數據庫

3.2 創建數據庫

3.3 創建表

3.4 數據庫增刪改查操作

3.4.1 插入操作

3.4.2 更新操作

3.4.3 查詢操作

3.4.4 刪除操作

4 MySQL 數據存儲招聘信息

4.1 MySQL 操作數據庫

4.2 代碼實現

5 本文小結


緊接前面所講,本文主要講述一個基於數據庫存儲的 BeautifulSoup 爬蟲,用於爬取網頁某網站的招聘信息,對數據進行增刪改查等各種操作,同時爲數據分析提供強大的技術保障,從而可以更加靈活地爲用戶提供所需數據。

1 知識圖譜和招聘網站

隨着“大數據”和“互聯網+”時代的到來,各種數量龐大、種類繁多的信息呈爆炸式增長,而且此類信息實時性強、結構化程度差,同時具有複雜的關聯性。因此,如何從海量數據中快速精確地尋找用戶所需的信息,就變得尤爲困難。在此背景下,通過自動化和智能化的搜索技術來幫助人們從互聯網中獲取所需的信息,就變得尤爲重要,知識圖譜(Knowledge Graph,KG)應運而生,它是一種通過理解用戶的查詢意圖,返回令用戶滿意的搜索結果而提出的新型網絡搜索引擎。

目前廣泛使用的搜索引擎包括谷歌,百度和搜狗等,此類引擎的核心搜索流程如下:

  • 首先,用戶向搜索引擎中輸入查詢詞;
  • 其次搜索引擎在後臺計算系統中檢索與查詢詞相關的網頁,通過內容相似性比較和鏈接分析,對檢索的網頁進行排序;
  • 最後,依次返回排序後的相關結果。

但是,由於信息檢索過程中沒有對查詢詞和返回網頁進行理解,也沒有對網頁內容進行深層次的分析和相關網頁的關係挖掘,所以搜索準確性存在明顯的缺陷。

現在爲了提升搜索引擎的準確性和理解用戶查詢的真實意圖,企業界提出了新一代搜索引擎或知識計算引擎,即知識圖譜。知識圖譜旨在從多個來源不同的網站、在線百科和知識庫中獲取描述真實世界的各種實體、概念、屬性和屬性值,並構建實體之間的關係以及融合屬性和屬性值,採用圖的形式存儲這些實體和關係信息。當用戶查詢相關信息時,知識圖譜可以提供更加準確的搜索結果,並真正理解用戶的查詢需求,對智能搜索郵政重要的意義。

知識圖譜構建過程中,需要從互聯網中爬取海量的數據,包括百科數據、萬維網廣義搜索數據、面向主題的網站定向搜索數據等。比如,當我們需要構建一個招聘就業相關的知識圖譜時,我們就需要爬取相常見的招聘網站,例如智聯招聘、大街網、前程無憂等等。

接下來將介紹如何爬取趕集網網站發佈的招聘信息並存處置本地 MySQL 數據庫中。

2 用 BeautifulSoup 爬取招聘信息

Python 調用 BeautifulSoup 擴展庫爬取趕集網網站的核心步驟如下:

  1. 分析網頁超鏈接的搜索規則,並探索分頁查找的跳轉方法;
  2. 分析網頁 DOM 樹結構,定位並分析所需信息的 HTML 源碼;
  3. 利用 Navicat for MySQL 工具創建智聯招聘網站對應的數據庫和表;
  4. Python 調用 BeautifulSoup 爬取數據並操作 MySQL 數據庫將數據存儲至本地。

2.1 分析網頁超鏈接及跳轉處理

招聘網站中的 “職位搜索” 頁面中包含一系列可供選擇的選項,如 “類別”、“區域”、“福利”、“月薪” 等等。

依次選擇第 1 頁數據:“http://bj.ganji.com/zpbiaoqian/p6o1/”、
              第 2 頁數據:“http://bj.ganji.com/zpbiaoqian/p6o2/”、
                  ...
我們可以推出第 n 頁數據:“http://bj.ganji.com/zpbiaoqian/p6on/”。

由此我們發現,發生變化的僅爲最後“/” 前一個數字變化。

在分析 URL 鏈接時,常常會遇到一些特殊符號,下面給出 URL 中常見的特殊符號含義:

URL 中常見的特殊符號
特殊符號 URL 中的含義 URL 編碼 ASCII 碼
空格(space) URL 中空格連接參數,也可用“+”連接 %20 32
# 表示書籤 %23 35
% 指定特殊字符 %25 37
& URL 中參數間的分隔符 %26 38
' URL 中的單引號 %27 39
+ URL 中 “+” 標識空格 %2B 43
- URL 中的減號 %2D 45
/ 用於分隔目錄和子目錄 %2F 47
; URL 中多個參數傳遞的分隔符 %3B 91
= URL 中指定參數的值 %3D 93
? 分隔實際的超鏈接和參數 %3F 95

對於查詢多頁結果的跳轉,是網站和系統開發中非常經典和常用的一種技術,跳轉頁面通常位於網頁的底部。

那麼網絡爬蟲是如何實現多頁跳轉的數據分析呢?這裏提供 3 中方法供借鑑:

  1. 通過分析網頁的超鏈接找到翻頁跳轉對應 URL 參數的規律,再使用 Python 拼接動態變化的 URL,對於不同的頁面分別進行訪問及數據爬取。文本採用的就是此方法,前文提到過,對於翻頁跳轉僅改變 URL 中的 “p” 值即可實現。
  2. 部分網頁可以採用 Selenium 等自動定位技術,通過分析網頁的 DOM 樹結構,動態定位網頁跳轉的連接或按鈕。比如調用 find_element_by_xpath() 函數定位網頁跳轉按鈕,然後操作鼠標控件自動點擊,從而跳轉到對應頁面。
  3. 如果網頁採用 POST 方法進行訪問,沒有在 URL 中指明跳轉的參數,則需要分析網頁跳轉鏈接對應的源碼。對跳轉頁面進行審查元素反饋的結果如下圖所示,然後通過爬取跳轉鏈接後再通過爬蟲訪問對應的 URL 及爬取數據。

例如,利用 BeautifulSoup 技術爬取智聯招聘信息就是採用分析網頁超鏈接 URL 的方法實現的,核心代碼如下:

i = 1
while i <= n:
    url = 'http://bj.ganji.com/zpbiaoqian/p6o' + str(i) + '/'
crawl(url)

首先通過字符串拼接訪問不同頁碼的 URL,然後調用 crawl(url) 函數循環爬取。其中,crawl() 函數用於爬取 url 中的指定內容。

2.2 DOM 樹節點分析及網頁爬取

 接下來需要對智聯招聘網站進行具體的 DOM 樹節點分析,並詳細講述利用 BeautifulSoup 技術定位節點及爬取的方法。

此時需要定位多個 <div> 標籤。調用 find_all() 函數獲取 class 屬性爲 “newlist” 的節點,然後通過 for 循環以此獲取 table 表格,核心代碼如下:

for tag in soup.find_all(attrs={"class": "con-list-zcon new-dl"})

定位到每塊招聘內容後,再爬取具體的內容,如張志偉名稱、公司名稱、職位月薪、工作地點、發佈日期等,並將這些信息賦給變量,存儲至本地 MySQL 數據庫中。
其中,獲取職位名稱和薪資信息的代碼如下:

zhiwei = tag.find(attrs={"class": "list-ga gj_tongji js-float"}).get_text()
xinxi = tag.find(attrs={"class": "s-butt s-bb1"}).get_text()

在定義網絡爬蟲時,通常需要將一些詳情頁面的超鏈接存儲至本地,比如下圖紅框中的超鏈接。

 在 BeautifulSoup 技術中,可以通過 get('href') 函數獲取超鏈接對應的 URL。

url_info = tag.find_all(attrs={"class": "list-ga gj_tongji js-float"})
for u in url_info:
    chaolianjie = u.get('href')
    print(chaolianjie)

至此,如何調用 BeautifulSoup 技術分析智聯招聘網站的信息、定位節點及爬取所需知識已經講解完畢。

3 Navicat for MySQL 工具操作數據庫

Navicat for MySQL 是一套管理和開發 MySQL 的理想解決方案,它支持單一程序,可直接連接到 MySQL 數據庫。Navicat for MySQL 爲數據庫管理、開發和維護提供了直觀而強大的圖形界面,給 MySQL 新手以及專業人士提供了全面管理數據庫的強大工具,以方便其操作數據庫。

3.1 連接數據庫

點擊“連接”按鈕,彈出“連接”對話框,在該對話框中輸入相關信息,如主機名、端口等。如果是本地數據庫,則在“主機”文本框中輸入“localhost”,在“端口”文本框中輸入“3306”,“用戶名”和“密碼”分別爲本地 MySQL 數據庫對應值,“用戶名”默認爲 root,“密碼”默認爲“123456”,連接名這裏我連接的是上一篇文章創建的數據庫“bookmanage”。

填寫好後,單機“連接測試”,當本地連接創建成功之後,點擊確定,就可以看到本地已經創建的數據庫了。

具體而言,我們可以看到上一篇文章創建的兩個表“books”和“students”。很顯然,比上一篇文章介紹的 MySQL 更加方便。

3.2 創建數據庫

利用 Navicat for MySQL 創建數據庫有兩種方法:

第一種是通過 SQL 語句創建數據庫,執行具體代碼如下:

create database test00

第二種是右擊鼠標,在彈出的快捷菜單中選擇“新建數據庫”:

然後再彈出的 “新建數據庫” 對話框中輸入數據庫名、字符集和排序規則,和第一種方法提到的一樣,將數據庫名設置爲“test00”,將字符集設置爲“utf8”,將排序規則設置爲“utf8_unicode_ci”

 

單擊確定,本地 MySQL數據庫就創建成功了。

3.3 創建表

利用 Navicat for MySQL 創建表也有兩種方法:
一種是單擊任務欄中的新建表按鈕進行創建、另一種是右擊空白處在彈出的快捷菜單中選擇“新建表”來創建。

假設新建表爲 T_USER_INFO,單擊“添加欄位”按鈕向表中插入響應字段,插入的字段包括:ID(序號)、USERNAME(用戶名)、PWD(密碼)、DW_NAME(單位名稱);同時還可以設置主鍵、非空屬性、添加註釋等。

 設置完成之後單擊“保存”按鈕,並在“輸入表名”文本框中輸入“T_USER_INFO”,此時數據庫的一張表就創建成功了。

當表創建好之後,單擊打開表按鈕可以查看當前表中所包含的數據。因爲該表目前沒有數據,所以顯示爲空。

當然,鼠標右擊可以對錶進行一系列的操作,感興趣讀者可進一步學習,這裏就不再贅述了。

3.4 數據庫增刪改查操作

SQL 語句支持的常用命令包括:

  • 數據庫定義語言(DDL):create、alter、drop
  • 數據庫操縱語言(DML):insert、delete、update、select
  • 數據控制語言(DCL):grant、revoke
  • 事務控制語言(TCL):commit、savepoint、rollback

3.4.1 插入操作

單擊“查詢”按鈕,再點擊“新建按鈕”,在彈出的對話框中進行 SQL 語句操作,完成之後單擊“運行”按鈕。

INSERT INTO T_USER_INFO
(ID,USERNAME,PWD,DW_NAME)
VALUES('1','zzr','123456','軟件學院')

 

3.4.2 更新操作

將表 T_USER_INFO 中的 ID 值爲 “1” 的數據更新

UPDATE T_USER_INFO SET USERNAME='rong',PWD='654321',DW_NAME='人工智能方向'
WHERE ID='1'

 

3.4.3 查詢操作

查詢表 T_USER_INFO 中 USERNAME 爲 “rong” 的信息,代碼如下:

SELECT * FROM T_USER_INFO WHERE USERNAME='rong';

 

3.4.4 刪除操作

刪除表 T_USER_INFO 中 ID 值爲 “1” 的信息,代碼如下:

DELETE FROM T_USER_INFO WHERE ID='1'  

 

4 MySQL 數據存儲招聘信息

4.1 MySQL 操作數據庫

首先需要創建表,SQL 語句代碼如下:

CREATE TABLE `PAQU_ZHAOPINXINXI`(
 `ID` int(11) NOT NULL AUTO_INCREMENT  COMMENT '序號',
 `zwmc` varchar(100) COLLATE utf8_bin DEFAULT NULL COMMENT '職位名稱',
 `xzdy` varchar(50) COLLATE utf8_bin DEFAULT NULL COMMENT '薪資待遇',
 `gzdd` varchar(50) COLLATE utf8_bin DEFAULT NULL COMMENT '工作地點',
 `gzjy` varchar(50) COLLATE utf8_bin DEFAULT NULL COMMENT '工作經驗',
 `zdxl` varchar(50) COLLATE utf8_bin DEFAULT NULL COMMENT '最低學歷',
 `zprs` varchar(50) COLLATE utf8_bin DEFAULT NULL COMMENT '招聘人數',
 PRIMARY KEY(`ID`)
)ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

 

4.2 代碼實現

import re
import requests
import MySQLdb
from bs4 import BeautifulSoup

# 存儲數據庫
# 參數:'職位名稱', '薪資待遇', '工作地點', '工作經驗', '最低學歷', '招聘人數'等
def DatabaseInfo(zwmc, xzdy, gzdd, gzjy, zdxl, zprs):
    try:
        conn = MySQLdb.connect(host = 'localhost', user='root', passwd='123456', port=3306, db='test00')
        cur = conn.cursor()   # 數據庫遊標

        # 設置編碼方式
        conn.set_character_set('utf8')
        cur.execute('SET NAMES utf8;')
        cur.execute('SET CHARACTER SET utf8;')
        cur.execute('SET character_set_connection=utf8;')

        # SQL 語句
        sql = '''
        insert into paqu_zhaopinxinxi(zwmc, xzdy, gzdd, gzjy, zdxl, zprs)values(%s, %s, %s, %s, %s, %s)
        '''

        cur.execute(sql, (zwmc, xzdy, gzdd, gzjy, zdxl, zprs))
        print('數據庫插入成功')
    except MySQLdb.Error as e:
        print('Mysql Error %d: %s' % (e.args[0], e.args[1]))
    finally:
        cur.close()
        conn.commit()
        conn.close()

# 爬蟲函數
def crawl(url):
    headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36'
        }
    html = requests.get(url, headers=headers).text
    # lxml:html解析庫(把HTML代碼轉化成Python對象)
    soup = BeautifulSoup(html, 'lxml')
    print('爬取信息如下:')

    i = 0
    for tag in soup.find_all(attrs={"class": "con-list-zcon new-dl"}):
        i = i + 1
        zwmc = tag.find(attrs={"class": "list-ga gj_tongji js-float"}).get_text()
        zwmc = zwmc.replace('\n', '')
        print(zwmc)
        # 其他信息
        xinxi = tag.find(attrs={"class": "s-butt s-bb1"}).get_text()
        print(xinxi)
        xzdy = re.findall('薪資待遇:(.*?)元', xinxi)
        gzdd = re.findall('工作地點:(.*?)\n', xinxi)
        gzjy = re.findall('工作經驗:(.*?)\n', xinxi)
        zdxl = re.findall('最低學歷:(.*?)\n', xinxi)
        zprs = re.findall('招聘人數:(.*?)人', xinxi)
        gzdd = gzdd[0]
        gzjy = gzjy[0]
        zdxl = zdxl[0]
        # 寫入 MySQL 數據庫
        print('寫入數據庫操作 ')
        DatabaseInfo(zwmc, xzdy, gzdd, gzjy, zdxl, zprs)

    else:
        print('爬取職位總數:', i)

# 主函數
if __name__ == '__main__':
    # 翻頁執行 crawl(url) 爬蟲
    i = 1
    while i <= 10:
        print('頁碼:', i)
        url = 'http://bj.ganji.com/zpbiaoqian/p6o{}/'.format(i)
        crawl(url)
        i = i + 1

 

至此,一個完整的使用 BeautifulSoup 技術爬取招聘網站信息並存儲至本地 MySQL 數據庫的實例已經講完。通過數據庫,用戶可以對數據進行增刪改查等各項操作,非常適合於海量數據爬取和數據分析操作。 

5 本文小結

前幾期文章分別講述了 BeautifulSoup 技術和 Python 操作數據庫,本文通過一個利用BeautifulSoup 技術爬取招聘信息的實例貫穿了所有知識點,將爬取的內容存儲至本地 MySQL 數據庫。通過這幾期文章希望能給您普及一些關於爬蟲的相關知識以及提供一些微不足道的爬蟲思路。


歡迎留言,一起學習交流~

感謝閱讀

END

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章