日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python爬取网站大数据_[Python]爬虫抓取大数据职位数据

發布時間:2023/12/10 python 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python爬取网站大数据_[Python]爬虫抓取大数据职位数据 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

《紐約時報》2012年2月的一篇專欄中所稱,“大數據”時代已經降臨,在商業、經濟及其他領域中,決策將日益基于數據和分析而作出,而并非基于經驗和直覺。隨大數據時代一起來來臨的,是越來越多的大數據工作崗位。在此,我們利用Python編程,抓取智聯招聘、51job等網站上面有關大數據的工作崗位數據。

爬蟲基礎知識

數據來源

網絡爬蟲的數據一般都來自服務器的響應結果,通常有html和json數據等,這兩種數據也是網絡爬蟲的主要數據來源。

其中html數據是網頁的源代碼,通過瀏覽器-查看源代碼可以直接查看,例如:

簡書主頁部分源碼示例

json是一種數據存儲格式,往往包含了最原始的數據內容,一般不直接顯示在網頁中,這里我們可以通過Chrome瀏覽器-開發者工具中的Network選項捕獲到服務器返回的json數據,例如:

簡書首頁json數據示例

數據請求

數據請求的方式一般有兩種:GET方法和POST方法。我們也可以通過Chrome瀏覽器來捕獲我們訪問一個瀏覽器時的所有請求。這里以簡書主頁為例,打開Chrome瀏覽器開發者工具(F12),切換到Network選項,在地址欄輸入http://www.jianshu.com/, 選擇XHR類型,可以看到一條請求的內容,打開Headers,在General中可以看到請求方式為GET方式,

其中的Request Headers便是我們訪問這個網頁時的請求數據,如下圖。

Request Headers

這個Headers可以用Python中的字典來表示,包含了用戶請求的一些信息,例如編碼、語言、用戶登陸信息、瀏覽器信息等。

下面還有一個Query String Parameters,這里面包含了用戶請求的一些參數,也是請求數據的一部分。

利用requests庫請求數據

利用Python構建數據請求的方式有很多,在python3中,主要有urllib和requests兩個類庫可以實現該功能。urllib是官方標準庫,其官方文檔傳送門。這里我們主要介紹第三方庫requests,它是基于urllib編寫的,比urllib用起來更加便捷,可以節約時間。

requests安裝方法:

$ pip install requests

利用requests構建數據請求主要方式:

import requests

req = request.get(url)

或者

import requests

req = requests.post(url)

其中,get()與post()中都可以添加headers、params等參數,以字典的形式傳遞即可。一般來說,簡單的網頁通過傳入url數據即可成功請求數據。不過一些網站采用了反爬蟲機制,需要我們傳入headers及params等參數,以模擬瀏覽器訪問、用戶登陸等行為,才可以正常請求數據。

利用webdriver請求數據

webdriver是一個用來進行復雜重復的web自動化測試的工具,能夠使用chrome、firefox、IE瀏覽器進行web測試,可以模擬用戶點擊鏈接,填寫表單,點擊按鈕等。因此,相對于requests庫來說,webdriver在模擬瀏覽器鼠標點擊滑動等事件上有著天然的優勢,并且真實模擬了瀏覽器的操作,不易被反爬蟲機制發現,因此是一個很好用的爬蟲工具。當然,其缺點在于速度較慢,效率不高。

webdriver安裝:

$ pip install selnium

除了安裝selnium庫,webdriver的運行還需要進行瀏覽器驅動的配置。Chrome、火狐和IE瀏覽器都有其配置方式,具體方法查看鏈接http://blog.163.com/yang_jianli/blog/static/1619900062014102833427464/。

這里我們以IE瀏覽器為例,做一個簡單的示范:

from selenium import webdriver

import os

iedriver = "IEDriverServer.exe"

os.environ["webdriver.ie.driver"] = iedriver

driver = webdriver.Ie(iedriver)

如此,IE瀏覽器配置完畢,其中"IEDriverServer.exe"是IE瀏覽器驅動的存儲路徑。

于是,我們我們訪問簡書網主頁數據只一步:

driver.get(http://www.jianshu.com/)

數據解析

使用requests請求下來的數據,可以利用.text()方法或者.content()方法訪問,對于文本請求,二者并無太大差別,主要在于編碼問題。具體用法可以參考官方文檔,這里不再贅述。使用webdriver請求下來的數據可以用.page_source屬性獲取。請求下來的數據一般包含了大量的網頁源代碼,如何將其解析以提取出我們想要的內容呢?

html類型數據解析

html語言即超文本標記語言,它是由一個個html標簽構成的,是結構化的語言,因此很容易從中匹配提取信息。這種類型的數據解析的方法有很多,比如利用正則表達式,按照html標簽的結構進行字符串匹配,或則利用lxml庫中的xpath方法使用xpath路徑定位到每一個節點、也有類似jQuery的PyQuery方法。這里我們主要介紹BeautifulSoup方法。

Beautiful Soup 是一個可以從HTML或XML文件中提取數據的Python庫.它能夠通過你喜歡的轉換器實現慣用的文檔導航,查找,修改文檔的方式.Beautiful Soup會幫你節省數小時甚至數天的工作時間。該介紹來源于其官方中文文檔,傳送門。利用BeautifulSoup我們能夠將html字符串轉化為樹狀結構,并非常快速地定位到每一個標簽。

目前版本是BeautifulSoup4,pip安裝方法:

$ pip install BeautifulSoup4

或者,下載bs4的源碼,然后解壓并運行:

$ python setup.py install

利用BeautifulSoup解析html數據的關鍵步驟為:

from bs4 import BeautifulSoup

soup = BeautifulSoup(req.contents, "html.parser")

如果采用webdriver請求數據,那么則是:

from bs4 import BeautifulSoup

soup = BeautifulSoup(driver.page_source, "html.parser")

如此,便將html數據轉換成BeautifulSoup中的樹狀結構。然后利用BeautifulSoup中的find()、find_all()等方法即可定位到每一個節點。詳情請參閱官方文檔。

json類型數據解析

json類型的數據已經是高度結構化的數據,跟Python中字典的表示形式一樣,因此在解析上十分方便。我們可以通過:

import json

data = json.loads(req.text)

直接讀取json數據,且能夠返回字典類型。

大數據職位數據爬蟲實戰

這里我們以51job網站為例,構建大數據相關職位的數據爬蟲。其中搜索關鍵詞為:

數據科學家

數據分析師

數據架構師

數據工程師

統計學家

數據庫管理員

業務數據分析師

數據產品經理

網頁分析

打開51job首頁http://www.51job.com/, 在搜索框中輸入“數據科學家”,將搜索框中的地區點開,去掉當前勾選的城市,即默認在全國范圍搜索。點擊“搜索”按鈕,得到搜索結果。這時我們將網址欄URL復制出來:

http://search.51job.com/list/000000,000000,0000,00,9,99,

%25E6%2595%25B0%25E6%258D%25AE%25E7%25A7%2591%25E5%25AD%25A6%25E5%25AE%25B6,

2,1.html?lang=c&stype=&postchannel=0000&workyear=99&cotype=99&degreefrom=99

&jobterm=99&companysize=99&providesalary=99&lonlat=0%2C0&radius=-1&ord_field=0

&confirmdate=9&fromType=&dibiaoid=0&address=&line=&specialarea=00&from=&welfare=

結果不止一頁,點擊第二頁,同樣將URL復制出來:

http://search.51job.com/list/000000,000000,0000,00,9,99,

%25E6%2595%25B0%25E6%258D%25AE%25E7%25A7%2591%25E5%25AD%25A6%25E5%25AE%25B6,

2,2.html?lang=c&stype=1&postchannel=0000&workyear=99&cotype=99&degreefrom=99

&jobterm=99&companysize=99&lonlat=0%2C0&radius=-1&ord_field=0

&confirmdate=9&fromType=&dibiaoid=0&address=&line=&specialarea=00&from=&welfare=

很容易發現,這兩段url唯一的不同在于".html"前面的數字1和2,因此它代表了頁碼。其中:

%25E6%2595%25B0%25E6%258D%25AE%25E7%25A7%2591%25E5%25AD%25A6%25E5%25AE%25B6

是一種URL編碼,翻譯成中文就是“數據科學家”,轉換方式可以使用urllib庫中的quote()方法:

import urllib.quote

keyword = '數據科學家'

url = quote(keyword)

我們可以通過第一次的搜索結果獲取頁碼數:

def GetPages(keyword):

keyword = quote(keyword, safe='/:?=')

url = 'http://search.51job.com/jobsearch/search_result.php?fromJs=1&jobarea=000000%2C00&district=000000&funtype=0000&industrytype=00&issuedate=9&providesalary=99&keyword='+keyword + \

'&keywordtype=2&curr_page=1&lang=c&stype=1&postchannel=0000&workyear=99&cotype=99&degreefrom=99&jobterm=99&companysize=99&lonlat=0%2C0&radius=-1&ord_field=0&list_type=0&fromType=14&dibiaoid=0&confirmdate=9'

html = requests.get(url)

soup = BeautifulSoup(html.content, "html.parser")

span = soup.find('div', class_='p_in').find('span', class_='td')

page_num = span.get_text().replace('共', '').replace('頁,到第', '')

return page_num

由此,便可實現針對特定關鍵詞的所有搜索結果的頁面的遍歷。

URL列表構建

打開搜索結果頁面,我們會發現,點擊職位名稱可以鏈接到每個職位的詳情頁面,也正是我們所需要的數據源。因此,我們只需要獲取所有的搜索結果中的職位名稱的超鏈接地址,便可以遍歷所有職位的詳細數據:

def GetUrls(keyword, page_num):

keyword = quote(keyword, safe='/:?=')

urls = []

p = page_num+1

for i in range(1, p):

url = 'http://search.51job.com/jobsearch/search_result.php?fromJs=1&jobarea=000000%2C00&district=000000&funtype=0000&industrytype=00&issuedate=9&providesalary=99&keyword='+keyword + \

'&keywordtype=2&curr_page=' + \

str(i) + \

'&lang=c&stype=1&postchannel=0000&workyear=99&cotype=99&degreefrom=99&jobterm=99&companysize=99&lonlat=0%2C0&radius=-1&ord_field=0&list_type=0&dibiaoid=0&confirmdate=9'

html = requests.get(url)

soup = BeautifulSoup(html.content, "html.parser")

ps = soup.find_all('p', class_='t1')

for p in ps:

a = p.find('a')

urls.append(str(a['href']))

s = random.randint(5, 30)

print(str(i)+'page done,'+str(s)+'s later')

time.sleep(s)

return urls

數據請求構建

在獲取了所有的職位數據的url之后,我們使用requests訪問這些url發現,并不能順利獲取數據。因此,可以考慮在請求中加入headers數據,其中包含cookie和User_Agent:

User_Agent = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36'

cookie = 'guid=14842945278988500031; slife=indexguide%3D1'

headers = {'User-Agent': User_Agent, 'cookie': cookie}

這樣,可以成功請求每個職位的詳情頁面數據:

數據解析

數據解析首先是明確數據需求,這里我們將數據盡可能多的抓取下來。

以職位要求一欄為例,我們通過訪問多個頁面對比發現,這一欄可能顯示的要求個數不一樣:

這里包括了經驗、學歷、招聘人數和發布時間

而這里則沒有對于經驗的要求。

利用瀏覽器開發者選項功能,查看這一欄的源碼:

這里職位的要求都放在一個class="sp4"的span中,通過查找功能可以發現沒有其他的class="sp4"的標簽,所以我們利用find_all()方法可以輕松定位到這些職位要求數據。

通過比較可以發現這最多的要求個數為4,所以在個數不確定的情況下,可以先新建一個包含四個空字符串元素的新數組,將所有的要求個數填入該數組,這樣可以保證不同網頁的數據都能獲取完整。

spans = soup.find_all('span', class_='sp4')

num = len(spans)

nav = ['', '', '', '']

for i in range(0, num-1):

nav[i] = spans[i].get_text().strip()

完整代碼如下:

# -*- coding: utf-8 -*-

from urllib.parse import quote

import requests

from bs4 import BeautifulSoup

import time

import random

def GetPages(keyword):

keyword = quote(keyword, safe='/:?=')

url = 'http://search.51job.com/jobsearch/search_result.php?fromJs=1&jobarea=000000%2C00&district=000000&funtype=0000&industrytype=00&issuedate=9&providesalary=99&keyword='+keyword + \

'&keywordtype=2&curr_page=1&lang=c&stype=1&postchannel=0000&workyear=99&cotype=99&degreefrom=99&jobterm=99&companysize=99&lonlat=0%2C0&radius=-1&ord_field=0&list_type=0&fromType=14&dibiaoid=0&confirmdate=9'

html = requests.get(url)

soup = BeautifulSoup(html.content, "html.parser")

span = soup.find('div', class_='p_in').find('span', class_='td')

page_num = span.get_text().replace('共', '').replace('頁,到第', '')

return page_num

def GetUrls(keyword, page_num):

keyword = quote(keyword, safe='/:?=')

urls = []

p = page_num+1

for i in range(1, p):

url = 'http://search.51job.com/jobsearch/search_result.php?fromJs=1&jobarea=000000%2C00&district=000000&funtype=0000&industrytype=00&issuedate=9&providesalary=99&keyword='+keyword + \

'&keywordtype=2&curr_page=' + \

str(i) + \

'&lang=c&stype=1&postchannel=0000&workyear=99&cotype=99&degreefrom=99&jobterm=99&companysize=99&lonlat=0%2C0&radius=-1&ord_field=0&list_type=0&dibiaoid=0&confirmdate=9'

html = requests.get(url)

soup = BeautifulSoup(html.content, "html.parser")

ps = soup.find_all('p', class_='t1')

for p in ps:

a = p.find('a')

urls.append(str(a['href']))

s = random.randint(5, 30)

print(str(i)+'page done,'+str(s)+'s later')

time.sleep(s)

return urls

def GetContent(url, headers):

html = requests.get(url, headers=headers)

soup = BeautifulSoup(html.content, "html.parser")

PositionTitle = str(soup.find('h1')['title'])

Location = soup.find('span', class_='lname').string

Salary = soup.find('strong').string

CompanyName = soup.find('p', class_='cname').get_text().strip()

CompanyType = soup.find(

'p', class_='msg ltype').get_text().strip().replace(' ', '').replace(' ', '').replace(' ', '').replace(' ', '')

spans = soup.find_all('span', class_='sp4')

num = len(spans)

nav = ['', '', '', '']

for i in range(0, num-1):

nav[i] = spans[i].get_text().strip()

Exp = nav[0]

Degree = nav[1]

RecruitNum = nav[2]

PostTime = nav[3]

Welfare = soup.find('p', class_='t2')

if str(type(Welfare)) == "":

Welfare = ''

else:

Welfare = Welfare.get_text().strip().replace('\n', '|')

PositionInfo = soup.find(

'div', class_='bmsg job_msg inbox').get_text().strip().replace('\n', '').replace('分享', '').replace('舉報', '').replace(' ', '').replace(' ', '').replace(' ', '').replace(' ', '').replace('\r', '')

PositionType = soup.find('span', class_='el')

if str(type(PositionType)) == "":

PositionType = ''

else:

PositionType = PositionType.get_text().strip().replace('\n', '')

Contact = soup.find('div', class_='bmsg inbox')

if str(type(Contact)) == "":

Contact = ''

else:

Contact = Contact.get_text().strip().replace(

' ', '').replace(' ', '').replace('地圖', '').replace('\n', '')

ConpanyInfo = soup.find('div', class_='tmsg inbox')

if str(type(ConpanyInfo)) == "":

ConpanyInfo = ''

else:

ConpanyInfo = ConpanyInfo.get_text().strip().replace(

'\n', '').replace(' ', '').replace(' ', '')

try:

record = PositionTitle+'\t'+Location+'\t'+Salary+'\t'+CompanyName+'\t'+CompanyType+'\t'+Exp+'\t'+Degree+'\t' + \

RecruitNum+'\t'+PostTime+'\t'+Welfare+'\t'+PositionInfo + \

'\t'+str(PositionType)+'\t'+str(Contact)+'\t'+str(ConpanyInfo)

except Exception as e:

record = ''

else:

pass

finally:

pass

return record

def main():

with open('keywords.txt', 'r', encoding='utf-8') as f:

keywords = f.readlines()

for keyword in keywords[1:]:

keyword = keyword.strip()

page_num = int(GetPages(keyword))

urls = GetUrls(keyword, page_num)

with open(keyword+'urls.txt', 'w', encoding='utf-8') as f:

for url in urls:

f.write(url+'\n')

User_Agent = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36'

cookie = 'guid=14842945278988500031; slife=indexguide%3D1'

headers = {'User-Agent': User_Agent, 'cookie': cookie}

with open(keyword+'urls.txt', 'r', encoding='utf-8') as f:

urls = f.readlines()

records = []

i = 0

for url in urls:

url = url.strip()

if url != '':

records.append(

GetContent(url, headers))

i += 1

s = random.randint(5, 30)

print(str(i)+'page done,'+str(s)+'s later')

time.sleep(s)

with open(keyword+'.txt', 'w', encoding='utf-8') as f:

for re in records:

f.write(re+'\n')

print(keyword+' Done---------------------------')

if __name__ == '__main__':

main()

總結

以上是生活随笔為你收集整理的python爬取网站大数据_[Python]爬虫抓取大数据职位数据的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。