python爬了51job 選定python,java和北上廣深四個城市 爬取對應地點 最高最低工資
寫入資料庫:
import urllib.request
import re
import sqlite3
#連線sqlite資料庫
conn = sqlite3.connect(r'D:\\db51job.db')
cursor = conn.cursor()
#IF NOT EXISTS當表不存在的時候,新建
cursor.execute('create table IF NOT EXISTS result51job(id integer primary key,key varchar(20),addr varchar(40),momin float,momax float)')
key = input("請輸入關鍵字:")
page = input("請輸入想要查詢的頁數:")
#控制查詢頁數
for i in range(1,int(page)+1):
#i必須是字元才能拼接
i=str(i)
#將關鍵字和頁數新增進url
url='https://search.51job.com/list/010000%252C020000%252C030200%252C040000,000000,0000,00,9,99,'+key+',2,'+i+'.html'
res=urllib.request.urlopen(url)
#讀取urllib.request返回的資料
html=res.read()
#read()返回的是二進位制序列,利用decode()轉換成html
html=html.decode('GBK')
retur = re. findall('<span class="t3">(北京|上海|廣州|深圳).*</span>\s*<span class="t4">(\d*\.?\d*)-(\d*\.?\d*)(\w)/(.*)</span>',html)
for i in range(1,len(retur)):
#資料處理:單位換算
minm = float( retur[i][1])
maxm = float(retur[i][2])
#round(x,n)函式:浮點數x 保留n位的四捨五入值
if retur[i][3] == '千':
minm =round(minm /10,2)
maxm =round(maxm /10,2)
if retur[i][4] == '年':
minm = round(minm /12,2)
maxm =round(maxm /12,2)
#插入資料
cursor.execute("insert into result51job(key,addr,momin,momax) values ('%s','%s','%f','%f')" % (key,retur[i][0],minm,maxm))
#commit()作用:執行完commit()之後,才會將插入的資料寫入資料庫
conn.commit();
#查詢資料庫,顯示result51job表中資料
cursor.execute("select * from result51job")
values=cursor.fetchall()
print(values)
#關閉遊標,關閉資料庫連線
cursor.close()
conn.close()
寫入檔案:
import urllib.request
import re
key = input("請輸入關鍵字:")
page = input("請輸入想要查詢的頁數:")
#每個關鍵字對應一個txt檔案,w+會覆蓋之前的內容
f = open(r'D:\\'+key+'.txt', 'w+')
f.write('關鍵字'+' '+'工作地點'+' '+'薪資min'+' '+' 薪資max'+'\r\n')
#for迴圈控制讀取哪幾頁,i表示頁數
for i in range(1,int(page)+1):
#i必須是字元才能拼接
i=str(i)
url='https://search.51job.com/list/010000%252C020000%252C030200%252C040000,000000,0000,00,9,99,'+key+',2,'+i+'.html'
res=urllib.request.urlopen(url)
#讀取urllib.request返回的資料
html=res.read()
#read()返回的是二進位制序列,利用decode()轉換成html
html=html.decode('GBK')
#正則表示式的應用
#每一個子表示式後都加了?,目的在於當薪資為空的情況出現時,也會顯示。
#[\u4e00-\u9fa5]表示漢字
#正則表示式中用幾個括號,返回的元組是幾個元素
#.可以匹配任何字元。但是不能匹配換行,改進:1,但是re.S可以讓</span>.*<span中的.匹配任意字元,包括換行符
#1.
#retur = re. findall('<span class="t3">(北京|上海|廣州|深圳).*</span>.*<span class="t4">(\d*\.?\d*)?-?(\d*\.?\d*)?(\w)?/?(.*)?</span>',html,re.S)
#這種改進方式的缺點:會開啟貪婪模式,即.*後面的所有字元都將被匹配掉,直到最後一行資料
#關閉貪婪模式的方法:在.*後面加上問號?:retur = re. findall('<span class="t3">(北京|上海|廣州|深圳).*</span>.*?<span class="t4">(\d*\.?\d*)?-?(\d*\.?\d*)?(\w)?/?(.*)?</span>',html,re.S)
#findall方法注意引數是兩個
#第一個引數是想要返回的格式
#第二個引數是搜尋範圍
retur = re. findall('<span class="t3">(北京|上海|廣州|深圳).*</span>\s*<span class="t4">(\d*\.?\d*)-(\d*\.?\d*)(\w)/(.*)</span>',html)
#每一個子表示式後都加了?,目的在於當薪資為空的情況出現時,也會顯示。
#爬取資料時面對特殊情況,可以直接捨去,因為總體資料量很大,並不會對最後結果造成太大影響
#retur = re. findall('<span class="t3">(北京|上海|廣州|深圳).*</span>\s*<span class="t4">(\d*\.?\d*)?-?(\d*\.?\d*)?(\w)?/?(.*)?</span>',html)
#retur = re. findall('<span class="t3">([\u4e00-\u9fa5]*)?-?(.*)?</span>\s*<span class="t4">(\d*\.?\d*)?-?(\d*\.?\d*)?(\w)?/?(.*)?</span>',html)
#address = re. findall('<span class="t3">([\u4e00-\u9fa5]*)?-?(.*)?</span>',html)
#money = re.findall('<span class="t4">(\d+\.*\d*)?-?(\d+\.*\d*)?(.*)</span>',html)
#money = re.findall('<span class="t4">(\d*\.?\d*)?-?(\d*\.?\d*)?萬?(.*)?</span>',html)
#money = re.findall('<span class="t4">(\d*\.?\d*)?-?(\d*\.?\d*)?(\w)?/?(.*)?</span>',html)
print(len(retur))
for i in range(1,len(retur)):
minm = float( retur[i][1])
maxm = float(retur[i][2])
#print(key+' '+address[i][0]+' '+money[i][0],' ',money[i][1])
if retur[i][3] == '千':
#round(x,n)函式:浮點數x 保留n位的四捨五入值
minm = round(minm /10,1)
maxm = round(maxm /10,1)
if retur[i][4] == '年':
minm = round(minm /12,1)
maxm =round(maxm /12,1)
result = key+' '+retur[i][0]+' '+str(minm)+' '+str(maxm) +' '+retur[i][3]+' '+retur[i][4]+'\r\n'
print(str(result))
f.write(str( key+' '+retur[i][0]+' '+str(minm)+' '+str(maxm) +'\r\n'))
#注意要關掉開啟的檔案,否則就會寫不進去
f.close()