Selenium學習四——利用Python爬取網頁多個頁面的表格資料並存到已有的excel中
利用Python爬取網頁多個頁面的表格資料並存到已有的excel中
1、具體要求
獲取牛客網->題庫->線上程式設計->劍指Offer網頁,獲取表格中的全部題目,儲存到本地excel中
2、技術要求
利用Selenium+Python獲取網頁,操作到table頁面
通過xlwt、xlrd、xlutils模組,將表格儲存到本地excel
xlwt:寫入excel(新建)
xlrd:讀取excel
xlutils:將xlrd.Book轉為xlwt.workbook,在原有的excel基礎上進行修改,新增等。
技術部落格參考:http://www.cnblogs.com/jiangzhaowei/p/5856604.html
3、主要程式碼
from xlutils.copy import copy import xlwt import xlrd import os def load_Table(page): #建立工作簿 wbk = xlwt.Workbook(encoding='utf-8', style_compression=0) #建立工作表 sheet = wbk.add_sheet('sheet 1', cell_overwrite_ok=True) excel = r"C:\xxx\test.xls" table_rows = driver.find_element_by_xpath("//*[@class='module-body offer-body']/table/tbody").find_elements_by_tag_name('tr') row = 20 for i, tr in enumerate(table_rows): if i==0 and page==0: table_cols1 = tr.find_elements_by_tag_name('th') for j, tc in enumerate(table_cols1): sheet.write(i, j, tc.text) wbk.save(excel) else: table_cols2 = tr.find_elements_by_tag_name('td') for j, tc in enumerate(table_cols2): #老的工作簿,開啟excel oldWb = xlrd.open_workbook(excel, formatting_info=True) #新的工作簿,複製老的工作簿 newWb = copy(oldWb) #新的工作表 newWs = newWb.get_sheet(0) newWs.write(i + page * row, j, tc.text) #os.remove(excel) newWb.save(excel) def switch_page(): #獲取頁數(除去首頁 、尾頁、上一頁和下一頁) pages = driver.find_element_by_xpath("//*[@class='pagination']/ul").find_elements_by_tag_name('li') t = len(pages)-4 for i in range(t): driver.find_element_by_link_text(str(i+1)).click() print i load_Table(i)
4、xlutils
引入模組
from xlutils.copy import copy
import xlwt
import xlrd
用xlwt建立工作簿工作表
#建立工作簿
wbk = xlwt.Workbook(encoding='utf-8', style_compression=0)
#建立工作表
sheet = wbk.add_sheet('sheet 1', cell_overwrite_ok=True)
寫入excel,並儲存到本地原有的excel中(用xlwt這樣儲存會覆蓋之前的內容)
sheet.write(i, j, tc.text) wbk.save(excel)
用xlrd開啟excel(formatting_info=true保證時間資料在copy時保持原樣)
oldWb = xlrd.open_workbook(excel, formatting_info=True)
複製excel檔案
newWb = copy(oldWb)
讀取複製的excel檔案的第一個sheet
newWs = newWb.get_sheet(0)
向這個sheet寫入資料
newWs.write(i, j, tc.text)
刪除原先存在的excel
os.remove(excel)
儲存這個新的excel檔案
newWb.save(excel)
5、全部程式碼
#coding:utf-8 from selenium import webdriver from selenium.webdriver.common.action_chains import ActionChains from xlutils.copy import copy import xlwt import xlrd import os import time ''' 下載牛客網首頁 > 線上程式設計 > 劍指Offer的題目表到excel 讀取excel裡的值 ''' driver = webdriver.Chrome() driver.get("https://www.nowcoder.com/") time.sleep(2) def switch_window(): #獲取當前控制代碼 h = driver.current_window_handle print h #跳轉到指定頁面 element = driver.find_element_by_xpath("//*[@class='nowcoder-navbar']/li[2]/a") ActionChains(driver).move_to_element(element).perform() driver.find_element_by_xpath("//*[@class='sub-nav']/li[3]/a").click() time.sleep(2) driver.find_element_by_xpath("//*[@class='topic-list clearfix']/li[1]").click() #切換到指定頁面 driver.close() all_h = driver.window_handles for i in all_h: if i != h: driver.switch_to.window(i) def load_Table(page): #建立工作簿 wbk = xlwt.Workbook(encoding='utf-8', style_compression=0) #建立工作表 sheet = wbk.add_sheet('sheet 1', cell_overwrite_ok=True) excel = r"C:\xxx\test.xls" table_rows = driver.find_element_by_xpath("//*[@class='module-body offer-body']/table/tbody").find_elements_by_tag_name('tr') row = 20 print row for i, tr in enumerate(table_rows): if i==0 and page==0: table_cols1 = tr.find_elements_by_tag_name('th') for j, tc in enumerate(table_cols1): sheet.write(i, j, tc.text) wbk.save(excel) else: table_cols2 = tr.find_elements_by_tag_name('td') for j, tc in enumerate(table_cols2): #老的工作簿,開啟excel oldWb = xlrd.open_workbook(excel, formatting_info=True) #新的工作簿,複製老的工作簿 newWb = copy(oldWb) #新的工作表 newWs = newWb.get_sheet(0) newWs.write(i + page * row, j, tc.text) os.remove(excel) newWb.save(excel) print 'save done' def switch_page(): pages = driver.find_element_by_xpath("//*[@class='pagination']/ul").find_elements_by_tag_name('li') t = len(pages) for i in range(t-4): driver.find_element_by_link_text(str(i+1)).click() print i load_Table(i) switch_window() switch_page() print 'done'
6、遇到的問題
本次試驗程式碼對於table換頁的處理較為粗暴,直接通過點選頁碼操作,for迴圈將每一頁新增到excel中去。由於是學的階段,還有其他的方法以後再完善。
①在新增過程中,一開始沒有使用xlutils,導致每次只有最後一頁資料,因為覆蓋了。
②後來新增的時候for語句沒有寫好,導致行亂序了,仔細一點就ok
注:數字變為字串前面要加str轉換,table的index從0開始,頁面元素定位從1開始
如
定位find_element_by_xxpath("//*[@class='search-input-wrap']/table/tbody/tr[4]/td[2]")