用Python寫一個小爬蟲吧!


學習了一段時間的web前端,感覺有點看不清前進的方向,於是就寫了一個小爬蟲,爬了51job上前端相關的崗位,看看招聘方對技術方面的需求,再有針對性的學習。

我在此之前接觸過Python,也寫過一些小腳本,於是決定用Python來完成這個小項目。

首先說說一個爬蟲的組成部分:

1.目標連接,就是我需要爬取信息的網頁的鏈接;

2.目標信息,就是網頁上我需要抓取的信息;

3.信息梳理,就是對爬取的信息進行整理。

下面我來說說整個爬蟲的設計思路:

總體思路:以“前端”關鍵字進行搜索,把搜索結果上面每一個招聘信息的鏈接爬取下來,再通過這些招聘職位的鏈接去抓取相應頁面上的具體要求。

1.先在51job上以“前端”為關鍵字進行搜索,從搜索結果來看,跟我的目標職位相似度還是很高的,所以用“前端”作為關鍵字是沒問題的。

2.獲取搜索結果的鏈接,通過比較1,2兩頁的鏈接,發現只有一個數字的差別,所以我可以直接更改這個數字來獲取每一頁的鏈接

3.在搜索結果頁面按F12可以看到網頁結構,按下左上角的鼠標按鈕,再去點網頁上的元素,網頁結構會自動展現相應的標簽

 

 

4.按下左上角的鼠標按鈕,再去點招聘信息的崗位鏈接,可以在網頁結構中看到,我們需要的每一個崗位的具體鏈接是放在一個a標簽里面的

5.再點進這個職位的詳情頁面,按F12查看網頁結構,再按左上角鼠標按鈕,之后點擊網頁上的職位信息,我發現職位信息都是放在一個div標簽里面,這個div有一個樣式類屬性class="bmsg job_msg inbox",具體的信息是放在這個div下的p標簽中,我查看了其他幾個招聘頁面,也是相同的結構

 

所以我的爬蟲要先爬取搜索結果頁面中的職位鏈接,再進到相應的鏈接爬取div標簽下p標簽的內容,最后對這些內容做一個詞頻分析。

 

為了簡化這個小項目的結構,我決定把這3個任務分成3個小腳本來執行。

首先是爬取搜索結果頁面中的職位鏈接。代碼如下

 1 #爬取職位鏈接這一步用到了3個庫
 2 import requests
 3 from bs4 import BeautifulSoup
 4 import chardet
 5 
 6 f = open('info.txt', 'a') # f是我存儲爬取信息的文本文件,使用追加模式,就是說后面寫入的信息會放在已有的信息后面,這樣就不會把之前的信息覆蓋掉
 7 url = 'https://search.51job.com/list/020000,000000,0000,00,9,99,%25E5%2589%258D%25E7%25AB%25AF,2,{}.html?' \
 8       'lang=c&stype=1&postchannel=0000&workyear=99&cotype=99&degreefrom=99&jobterm=99&companysize=99&' \
 9       'lonlat=0%2C0&radius=-1&ord_field=0&confirmdate=9&fromType=4&dibiaoid=0&address=&line=&' \
10       'specialarea=00&from=&welfare=#top' # url里面關乎頁面跳轉的數字我用{}占位,后面可以通過format函數動態替換
11 header = {
12     'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 '
13                   'Safari/537.36',
14     'Connection': 'keep-alive',
15     }# header是為了把爬蟲偽裝的像是正常的訪問。
16 
17 #for循環結構,循環10次,也就是說爬取10頁上面的職位鏈接
18 for i in range(11):
19   # 用requests庫的get方法與服務器進行鏈接,返回一個requests.models.Response的類
20     pageConnect = requests.get(url.format(i), headers=header)
21   #用chardet庫的detect方法獲取網頁編碼格式,返回的是dict字典,具體的編碼格式在encoding這個鍵對應的值中
22     pageConnect.encoding = chardet.detect(pageConnect.content)['encoding']
23   #設置好編碼格式后,用text方法把Response這個類轉化為字符串供beautifulSoup處理
24     page = pageConnect.text
25   #使用BeautifulSoup函數把page字符串轉化為一個BeautifulSoup對象,lxml是解析器的類型
26     soup = BeautifulSoup(page, 'lxml')
27   #使用BeautifulSoup對象的select方法,可以用css選擇器把存放有職位鏈接的a標簽選出來
28   #每一個a標簽都是放在class=el的div標簽下class=t1的p標簽下
29     aLabel = soup.select('div.el > p.t1 a')
30   #每一個搜索結果頁有50個職位,也就有50個a標簽,通過for循環,獲取每個a標簽的title屬性,href屬性
31   #title屬性存放了職位名稱,我可以通過職位名稱把不是我需要的職位鏈接篩選出去
32   #href屬性存放了每一個職位的鏈接
33     for each in aLabel:
34       #把這些信息存放到f也就是info.txt這個文本中
35         print(each['title'], each['href'], file=f)

 

接着要做的就是爬取每一個鏈接頁面上的職位要求了

代碼如下

 1  import requests
 2  from bs4 import BeautifulSoup
 3  import chardet
 4 
 5  #打開我存放鏈接的文本,使用readlines方法讀取文本內容,返回的是一個list列表,每一行為列表中的一項
 6  with open('info.txt') as info:
 7      link = info.readlines()
 8  #打開一個文本文件,存放抓取到的職位要求,編碼格式設為utf-8
 9  job = open('job.txt', 'a', encoding='UTF-8')
10  header = {
11      'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 '
12                    'Safari/537.36',
13      'Connection': 'keep-alive',
14      }
15  
16  for each in link:
17    #info.txt中存放的信息是職位名 + 鏈接:Web前端開發工程師 https://*****  
18    #所以先對列表中的每一項,也就是說一個字符串調用find方法,搜索關鍵字http,返回的是一個整數,表示的是字符串中http開頭h的索引值
19      index = each.find('http')
20    #利用這個索引值,可以獲取字符串中鏈接的部分
21      url = each[index:]
22      pageConnect = requests.get(url, headers=header)
23      pageConnect.encoding = chardet.detect(pageConnect.content)['encoding']
24      page = pageConnect.text
25      soup = BeautifulSoup(page, 'lxml')
26    #所有的職位要求是放在一個div中,它的樣式類為class=bmsg job_msg inbox,div中的p標簽包含具體的信息,返回的是一個list列表
27      div = soup.select('div.bmsg.job_msg.inbox p')
28    #經過測試發現,最后2個p標簽存放着關鍵字,所以去掉
29      jobInfo = div[:-2]
30      for eachInfo in jobInfo:
31      #每個列表項存放着如<p>***</P>的bs4.element.Tag,要獲取其中文字部分,要使用.string方法
32        print(eachInfo.string, file=job)

 

最后job.txt中存放着我抓取到的所有職位要求,但是我不可能一條一條的去看,所以借助jieba這個庫進行分詞

1 import jieba
2 
3 with open('job.txt', encoding='utf-8') as job:
4     info = job.readlines()
5 for eachLine in info:
6     for eachWord in jieba.cut(eachLine):
7         print(eachWord)

 

為了節省時間,分詞結果直接打印出來,然后復制到excel表中,使用數據透視表統計一下,最后整理結果如下

這是一個非常簡陋的小項目,不過它也實現了我的目標。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM