如何爬取前程無憂python職位資訊
爬取前程無憂python職位資訊的步驟:
1、分析網頁,查詢需要的資料所在位置
網站地址:
%2520,2,1.html
(1)進入該網站,輸入關鍵詞“python”,如下:
可以發現輸入關鍵字後連結也對應出現了“python”關鍵字,根據這個規律可以實現進入任意搜尋關鍵詞的網頁。
(2)緊接著檢查網頁原始碼,看看網頁資料是否在原始碼內:
可以發現職位的詳情網址、職位名稱、薪資等資訊都顯示在網頁原始碼內,確定改資料為靜態資料,可以使用xpath解析語法來獲取。職位的詳情頁也可以根據此方法來判斷是否存在網頁原始碼,結果也是存在的。
(3)我們點選第二頁後發現網址也對應發生改變:
第一頁:
python,2,1.html
第二頁:
python,2,2.html
可以發現連結的倒數第一個數字發生了變化,由1變成2,由此可以判斷這個位置的數字是控制頁數的。接下來可以實現程式碼了。
2、匯入需要使用到的模組,編寫爬取函式以及儲存函式
(1)爬蟲使用到的模組:
import requests # 網路請求庫 from lxml import etree # 解析模組 import time # 時間模組 import csv # csv模組 import urllib3 # urllib3,主要用來關掉警告資訊 from requests.adapters import HTTPAdapter # HTTPAdapter,主要用來重新請求
(2)__init__初始化函方法:
def __init__(self): self.keyword = input("請輸入搜尋關鍵詞:") self.url = '{},2,{}.html' # 網頁url self.headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36'} # 設定請求頭 self.requests = requests.Session() # 建立csv物件,用於儲存會話 self.requests.mount('http://', HTTPAdapter(max_retries=3)) # 增加http請求次數,這裡是因為有時候我們這邊網路不好,導致請求出不來,或者對方沒響應給我們,導致報錯。新增這段程式碼可以重新請求 self.requests.mount('https://', HTTPAdapter(max_retries=3)) # 增加https請求次數,這裡是因為有時候我們這邊網路不好,導致請求出不來,或者對方沒響應給我們,導致報錯。新增這段程式碼可以重新請求 self.header = ['position', 'company', 'wages', 'place', 'education','work_experience', 'release_date', 'limit_people', 'address', 'company_type', 'company_size', 'industry', 'point_information'] # csv頭部資訊 self.fp = open('python招聘職位.csv', 'a', encoding='utf-8', newline='') # 建立儲存csv的控制程式碼 self.writer = csv.DictWriter(self.fp, self.header) # 建立writer,用於後面寫入資料 self.writer.writeheader() # 保寫入csv頭部資訊 urllib3.disable_warnings() # 下面的請求中移除了ssl認證會生成警告資訊,所以這裡取消警告輸出
(3)下面單獨實現一個可以獲取總頁數的方法:
def get_end_page(self): # 該函式可以獲取最後一頁的頁數 response = self.requests.get(self.url.format(self.keyword, str(1)), headers=self.headers, timeout=4, verify=False) text = response.content.decode('gb18030') # 使用gb18030解碼幾乎適用所有網頁,不適用的網頁只有個別,是從其他網站載入的,解析方式不一樣,直接忽略掉。 html = etree.HTML(text) txt = "".join(html.xpath("//div[@class='dw_page']//div[@class='p_in']/span[1]/text()")) # 獲取包含總頁數的一段字串txt end_page = int(txt.split('頁', 1)[0][1:]) # 從字串txt提取總頁數 return end_page
(4)獲取詳情頁資訊的方法:
def parse_url(self, url): response = self.requests.get(url=url, headers=self.headers, timeout=5, verify=False) try: # 這裡可能會出現解碼錯誤,因為有個別很少的特殊網頁結構,另類來的,不用管 text = response.content.decode('gb18030') except Exception as e: print("特殊網頁位元組解碼錯誤:{},結束執行該函式,解析下一個詳情url".format(e)) return # 直接結束函式,不解析 html = etree.HTML(text) try: # 如果職位名獲取不到會異常,因為這個詳情url的網頁形式也很特殊,很少會出現這種url,所以就return結束函式,進入下一個詳情url position = html.xpath("//div[@class='tHeader tHjob']//div[@class='cn']/h1/@title")[0] # 職位名 except: return company = "".join(html.xpath("//div[@class='tHeader tHjob']//div[@class='cn']/p[1]/a[1]//text()")) # 公司名 wages = "".join(html.xpath("//div[@class='tHeader tHjob']//div[@class='cn']/strong/text()")) # 工資 informations = html.xpath("//div[@class='tHeader tHjob']//div[@class='cn']/p[2]/text()") # 獲取地點經驗學歷等資訊 informations = [i.strip() for i in informations] # 將元素兩邊去除空格 place = informations[0] # 工作地點 education = "".join([i for i in informations if i in '本科大專應屆生在校生碩士']) # 透過列表推導式獲取學歷 work_experience = "".join([i for i in informations if '經驗' in i ]) # 獲取工作經驗 release_date = "".join([i for i in informations if '釋出' in i]) # 獲取釋出時間 limit_people = "".join([i for i in informations if '招' in i]) # 獲取招聘人數 address = "".join(html.xpath("//div[@class='tCompany_main']/div[2]/div[@class='bmsg inbox']/p/text()")) # 上班地址 company_type = "".join(html.xpath("//div[@class='tCompany_sidebar']/div[1]/div[2]/p[1]/@title")) # 公司型別 company_size = "".join(html.xpath("//div[@class='tCompany_sidebar']/div[1]/div[2]/p[2]/@title")) # 公司規模 industry = "".join(html.xpath("//div[@class='tCompany_sidebar']/div[1]/div[2]/p[3]/@title")) # 所屬行業 point_information = html.xpath('//div[@class="tBorderTop_box"]//div[@class="bmsg job_msg inbox"]//text()') point_information = "".join([i.strip() for i in point_information if i != 'xa0xa0xa0xa0']).replace("xa0", "") # 職位資訊 if len(point_information) == 0: # 有一些詳情url的職位資訊的html標籤有點區別,所以判斷一下,長度為0就換下面的解析語法 point_information = html.xpath('//div[@class="tBorderTop_box"]//div[@class="bmsg job_msg inbox"]/text()') point_information = "".join([i.strip() for i in point_information]) if len(point_information) == 0: # 有一些詳情url的職位資訊的html標籤有點區別,所以判斷一下,長度為0就換下面的解析語法 point_information = html.xpath('//div[@class="tBorderTop_box"]//div[@class="bmsg job_msg inbox"]//tbody//text()') point_information = "".join([i.strip() for i in point_information]) if len(point_information) == 0: # 有一些詳情url的職位資訊的html標籤有點區別,所以判斷一下,長度為0就換下面的解析語法 point_information = html.xpath('//div[@class="tBorderTop_box"]//div[@class="bmsg job_msg inbox"]/ol//text()') point_information = "".join([i.strip() for i in point_information]) item = {'position':position, 'company':company, 'wages':wages, 'place':place, 'education':education, 'work_experience':work_experience, 'release_date':release_date, 'limit_people':limit_people, 'address':address, 'company_type':company_type, 'company_size':company_size, 'industry':industry,'point_information':point_information} # 把解析到的資料放入字典中 self.writer.writerow(item) # 儲存資料
(5)完整程式碼:
#!/usr/bin/env python # _*_ coding:utf-8 _*_ # # @Version : 1.0 # @Time : xxx # @Author : xx # @File : 51job.py import requests # 網路請求庫 from lxml import etree # 解析模組 import time # 時間模組 import csv # csv模組 import urllib3 # urllib3,主要用來關掉警告資訊 from requests.adapters import HTTPAdapter # HTTPAdapter,主要用來重新請求 class PositionSpider(object): def __init__(self): self.keyword = input("請輸入搜尋關鍵詞:") self.url = '{},2,{}.html' # 網頁url self.headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36'} # 設定請求頭 self.requests = requests.Session() # 建立csv物件,用於儲存會話 self.requests.mount('http://', HTTPAdapter(max_retries=3)) # 增加http請求次數,這裡是因為有時候我們這邊網路不好,導致請求出不來,或者對方沒響應給我們,導致報錯。新增這段程式碼可以重新請求 self.requests.mount('https://', HTTPAdapter(max_retries=3)) # 增加https請求次數,這裡是因為有時候我們這邊網路不好,導致請求出不來,或者對方沒響應給我們,導致報錯。新增這段程式碼可以重新請求 self.header = ['position', 'company', 'wages', 'place', 'education','work_experience', 'release_date', 'limit_people', 'address', 'company_type', 'company_size', 'industry', 'point_information'] # csv頭部資訊 self.fp = open('python招聘職位.csv', 'a', encoding='utf-8', newline='') # 建立儲存csv的控制程式碼 self.writer = csv.DictWriter(self.fp, self.header) # 建立writer,用於後面寫入資料 self.writer.writeheader() # 保寫入csv頭部資訊 urllib3.disable_warnings() # 下面的請求中移除了ssl認證會生成警告資訊,所以這裡取消警告輸出 def get_end_page(self): # 該函式可以獲取最後一頁的頁數 response = self.requests.get(self.url.format(self.keyword, str(1)), headers=self.headers, timeout=4, verify=False) text = response.content.decode('gb18030') # 使用gb18030解碼幾乎適用所有網頁,不適用的網頁只有個別,是從其他網站載入的,解析方式不一樣,直接忽略掉。 html = etree.HTML(text) txt = "".join(html.xpath("//div[@class='dw_page']//div[@class='p_in']/span[1]/text()")) # 獲取包含總頁數的一段字串txt end_page = int(txt.split('頁', 1)[0][1:]) # 從字串txt提取總頁數 return end_page def get_url(self, count): num = 0 # 用於判斷是請求響應失敗,還是頁數到底了 while True: # 這裡設定while是因為有時候請求太快,響應跟不上,會獲取不到資料。也可以使用睡眠的方法。 num += 1 response = self.requests.get(url=self.url.format(self.keyword, count), headers=self.headers, timeout=4, verify=False) # 發起get請求 text = response.content.decode('gb18030') html = etree.HTML(text) detail_urls = html.xpath("//div[@class='dw_table']/div[@class='el']//p/span/a/@href") # 使用xpath語法提取該頁所有詳情url if len(detail_urls) == 0: # 列表長度為零就重新請求,這一步是因為有時候傳送請求過快,對方伺服器跟不上我們速度,導致返回資料為空,所以下面睡眠一下,重新請求 time.sleep(2) # 睡眠一下 continue else: break return detail_urls # 返回列表,將詳情url給下一個函式進行解析獲取資料 def parse_url(self, url): response = self.requests.get(url=url, headers=self.headers, timeout=5, verify=False) try: # 這裡可能會出現解碼錯誤,因為有個別很少的特殊網頁結構,另類來的,不用管 text = response.content.decode('gb18030') except Exception as e: print("特殊網頁位元組解碼錯誤:{},結束執行該函式,解析下一個詳情url".format(e)) return # 直接結束函式,不解析 html = etree.HTML(text) try: # 如果職位名獲取不到會異常,因為這個詳情url的網頁形式也很特殊,很少會出現這種url,所以就return結束函式,進入下一個詳情url position = html.xpath("//div[@class='tHeader tHjob']//div[@class='cn']/h1/@title")[0] # 職位名 except: return company = "".join(html.xpath("//div[@class='tHeader tHjob']//div[@class='cn']/p[1]/a[1]//text()")) # 公司名 wages = "".join(html.xpath("//div[@class='tHeader tHjob']//div[@class='cn']/strong/text()")) # 工資 informations = html.xpath("//div[@class='tHeader tHjob']//div[@class='cn']/p[2]/text()") # 獲取地點經驗學歷等資訊 informations = [i.strip() for i in informations] # 將元素兩邊去除空格 place = informations[0] # 工作地點 education = "".join([i for i in informations if i in '本科大專應屆生在校生碩士']) # 透過列表推導式獲取學歷 work_experience = "".join([i for i in informations if '經驗' in i ]) # 獲取工作經驗 release_date = "".join([i for i in informations if '釋出' in i]) # 獲取釋出時間 limit_people = "".join([i for i in informations if '招' in i]) # 獲取招聘人數 address = "".join(html.xpath("//div[@class='tCompany_main']/div[2]/div[@class='bmsg inbox']/p/text()")) # 上班地址 company_type = "".join(html.xpath("//div[@class='tCompany_sidebar']/div[1]/div[2]/p[1]/@title")) # 公司型別 company_size = "".join(html.xpath("//div[@class='tCompany_sidebar']/div[1]/div[2]/p[2]/@title")) # 公司規模 industry = "".join(html.xpath("//div[@class='tCompany_sidebar']/div[1]/div[2]/p[3]/@title")) # 所屬行業 point_information = html.xpath('//div[@class="tBorderTop_box"]//div[@class="bmsg job_msg inbox"]//text()') point_information = "".join([i.strip() for i in point_information if i != 'xa0xa0xa0xa0']).replace("xa0", "") # 職位資訊 if len(point_information) == 0: # 有一些詳情url的職位資訊的html標籤有點區別,所以判斷一下,長度為0就換下面的解析語法 point_information = html.xpath('//div[@class="tBorderTop_box"]//div[@class="bmsg job_msg inbox"]/text()') point_information = "".join([i.strip() for i in point_information]) if len(point_information) == 0: # 有一些詳情url的職位資訊的html標籤有點區別,所以判斷一下,長度為0就換下面的解析語法 point_information = html.xpath('//div[@class="tBorderTop_box"]//div[@class="bmsg job_msg inbox"]//tbody//text()') point_information = "".join([i.strip() for i in point_information]) if len(point_information) == 0: # 有一些詳情url的職位資訊的html標籤有點區別,所以判斷一下,長度為0就換下面的解析語法 point_information = html.xpath('//div[@class="tBorderTop_box"]//div[@class="bmsg job_msg inbox"]/ol//text()') point_information = "".join([i.strip() for i in point_information]) item = {'position':position, 'company':company, 'wages':wages, 'place':place, 'education':education, 'work_experience':work_experience, 'release_date':release_date, 'limit_people':limit_people, 'address':address, 'company_type':company_type, 'company_size':company_size, 'industry':industry,'point_information':point_information} # 把解析到的資料放入字典中 self.writer.writerow(item) # 儲存資料 if __name__ == '__main__': print("爬蟲開始") spider = PositionSpider() # 建立類的物件spider end_page = spider.get_end_page() # 獲取該職位的總頁數 print("總頁數:{}".format(str(end_page))) for count in range(1, end_page+1): # 遍歷總頁數 detail_urls = spider.get_url(count) # 獲取詳情url方法,接收列表 for detail_url in detail_urls: # 遍歷獲取的詳情url time.sleep(0.2) # 稍微睡眠一下 spider.parse_url(detail_url) # 解析詳情頁獲取資料 print("已爬取第{}頁".format(count)) spider.fp.close() # 關閉控制程式碼 print("爬取結束")
採集結果:
更多Python知識,請關注:!!
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/2508/viewspace-2833245/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- python爬取前程無憂和拉勾資料分析崗位並分析Python
- 前程無憂崗位資料爬取+Tableau視覺化分析視覺化
- 利用Python爬蟲獲取招聘網站職位資訊Python爬蟲網站
- 拉勾網職位資料爬取
- 前程無憂財報:2012年前程無憂總營收為人民幣3.808億元 同比增長17.3%營收
- 前程無憂:84.7%的職場人在下班後仍會關注工作相關資訊
- 爬取 Boss 直聘網上海區域 PHP 職位資訊資料並分析PHP
- python爬蟲——爬取大學排名資訊Python爬蟲
- python爬取北京租房資訊Python
- 前程無憂:2018年Q1酒店/旅遊行業人才需求資訊行業
- python爬蟲--爬取鏈家租房資訊Python爬蟲
- 前程無憂:調查顯示網店、代購、專車成為最多人從事的兼職工作
- 前程無憂:2021大學生就業形勢報告就業
- 前程無憂執行長向Recruit售100萬股股票UI
- python itchat 爬取微信好友資訊Python
- Python爬蟲爬取淘寶,京東商品資訊Python爬蟲
- 小白學 Python 爬蟲(25):爬取股票資訊Python爬蟲
- 前程無憂助力,再次舉辦湖北武漢網路專場招聘會
- Python爬蟲實戰:爬取淘寶的商品資訊Python爬蟲
- 前程無憂:2022遠端辦公人群實感調查
- 用python爬取鏈家的租房資訊Python
- Python 招聘資訊爬取及視覺化Python視覺化
- python爬蟲58同城(多個資訊一次爬取)Python爬蟲
- 實戰爬取BOOS直聘,找到最適合你的職位
- python-python爬取豆果網(菜譜資訊)Python
- [Python3]selenium爬取淘寶商品資訊Python
- Python3爬取貓眼電影資訊Python
- 前程無憂釋出一季度財報 淨利潤為420萬美元
- Java爬蟲-爬取疫苗批次資訊Java爬蟲
- [python爬蟲] 招聘資訊定時系統 (一).BeautifulSoup爬取資訊並儲存MySQLPython爬蟲MySql
- 如何更無憂的使用MacMac
- python爬蟲如何獲取表情包Python爬蟲
- 前程無憂:調查顯示61% 的畢業生認為 “找工作比較難”
- Python 爬蟲獲取網易雲音樂歌手資訊Python爬蟲
- Python筆記:網頁資訊爬取簡介(一)Python筆記網頁
- Python爬取天氣資訊並語音播報Python
- python爬蟲,獲取中國工程院院士資訊Python爬蟲
- python實現微博個人主頁的資訊爬取Python