學習隨筆-python動態爬取空氣質量網數據的實現

想爬取https://www.aqistudy.cn/空氣質量網上的河北省空氣歷史數據,javascript

 

 

以前使用python寫過基於scrapy的爬蟲,想故技重施發現爬取不到想要的數據,仔細看過網頁源代碼後發現表格中的數據是動態加載的,使用開發者工具想要查看傳輸的數據結果php

發現數據被加密了,百度過解決辦法後決定選擇selenium實現動態的數據爬取html

1、什麼是selenium?java

selenium 是一個用於Web應用程序測試的工具。Selenium測試直接運行在瀏覽器中,就像真正的用戶在操做同樣,selenium用於爬蟲,主要是用來解決javascript渲染的問題python

2、selenium基本實現web

 

1.聲明瀏覽器對象sql

browser=webdriver.Chrome('C:\ProgramFiles(x86)\Google\Chrome\Application\chromedriver.exe')
在這裏須要安裝相應的webdriver須要注意兩點
(1)是下載時注意瀏覽器版本和webdriver的版本號對應
(2)網上關於webdriver安裝都要求配置環境變量,本人經實驗發現程序仍是會報找不到path,所以我直接將webdriver放在chrome路徑下,然後在聲明時直接貼上路徑

2.訪問頁面
browser.get("http://www.baidu.com")
在這裏我觀察了空氣質量網的url,發現格式爲
https://www.aqistudy.cn/historydata/daydata.php?city=城市名&month=年月
3.查找元素與selenium操做
這裏selenium提供了不少函數讓咱們進行操做,其中很關鍵的兩個就是經過xpath查找元素find_elements_by_xpath以及JavaScript的執行命令execute_script,而我就很厲害了,pands中有一個函數叫作read_html
pd.read_html(browser.page_source, header=0)[0]
經過它的實現我直接得到頁面中表格的dataframe格式,怎麼處理固然就是任我揉捏了
3.關閉browser
browser.close()
 

在執行過程當中,出現了爬取結果爲空的狀況,判斷緣由爲頁面未加載完成,設置time.sleep(1)發現並不能解決問題,在使用八爪魚採集器採集過程當中,發現八爪魚對未採集到的界面的處理是重複採集,所以在採集字段後接了一條判斷語句,若結果爲空,則重複採集chrome

詳見代碼數據庫

 1 #coding=utf-8
 2 from selenium import webdriver  3 import cx_Oracle                                     #引用模塊cx_Oracle
 4 import pandas as pd  5 import os  6 #若數據爲空,則重複採集
 7 def paqu(uurl):  8  browser.get(uurl)  9     dfs = pd.read_html(browser.page_source, header=0)[0] 10     if len(dfs)>1: 11         return dfs 12     else: 13         return paqu(uurl) 14 os.environ['NLS_LANG'] = 'SIMPLIFIED CHINESE_CHINA.UTF8'      #防止oracle數據亂碼
15 conn=cx_Oracle.connect('Xho', 'sys', 'localhost:1521/orcl')    #鏈接數據庫
16 cursor=conn.cursor()#獲取cursor遊標
17 
18 #聲明瀏覽器對象
19 browser = webdriver.Chrome('C:\Program Files (x86)\Google\Chrome\Application\chromedriver.exe') 20 base_url='https://www.aqistudy.cn/historydata/daydata.php?city='
21 city=['石家莊','保定','唐山','邯鄲','邢臺','滄州','衡水','廊坊','承德','秦皇島','張家口'] 22 
23 year=[201301,201401,201501,201601,201701,201801] 24 list_data=[] 25 list_row=[] 26 for p in range(len(city)): 27     for i in year: 28         for j in range(12): 29             num = i + j 30             if num > 201311 and num < 201809: 31                 uurl=base_url+city[p]+'&month='+str(num) 32                 dfs=paqu(uurl) 33                 #time.sleep(1)
34                 dfs['city']=city[p] 35                 for s in range(0, len(dfs)): 36                     date = dfs.iloc[s, 0] 37  list_row.append(date) 38                     aqi = dfs.iloc[s, 1] 39  list_row.append(aqi) 40                     grade = dfs.iloc[s, 2] 41  list_row.append(grade) 42                     pm25 = dfs.iloc[s, 3] 43  list_row.append(pm25) 44                     pm10 = dfs.iloc[s, 4] 45  list_row.append(pm10) 46                     so2 = dfs.iloc[s, 5] 47  list_row.append(so2) 48                     co = dfs.iloc[s, 6] 49  list_row.append(co) 50                     no2 = dfs.iloc[s, 7] 51  list_row.append(no2) 52                     o3 = dfs.iloc[s, 8] 53  list_row.append(o3) 54                     chsh=dfs.iloc[s,9] 55  list_row.append(chsh) 56 
57  list_data.append(list_row) 58                     list_row=[] 59     for n in range(len(list_data)): 60         sql = 'insert into AIR_ZL (A_DATE,AQI,GRADE,PM25,PM10,SO2,CO,NO2,O3_8H,CITY) VALUES (:A_DATE,:AQI,:GRADE,:PM25,:PM10,:SO2,:CO,:NO2,:O3_8H,:CITY)'
61         x = cursor.execute(sql, (list_data[n][0], float(list_data[n][1]), list_data[n][2],float(list_data[n][3]),float(list_data[n][4]),float(list_data[n][5]),float(list_data[n][6]),float(list_data[n][7]),float(list_data[n][8]),list_data[n][9])) 62  conn.commit(); 63     list_data=[] 64 cursor.close()  # 關閉cursor
65 conn.close()  # 關閉鏈接
66 browser.close()
相關文章
相關標籤/搜索