当前位置:   article > 正文

python+selenium爬虫自动化批量下载文件_python自动化selenium下载excel文件

python自动化selenium下载excel文件

一、项目需求

在一个业务网站有可以一个个打开有相关内容的文本,需要逐个保存为TXT,数据量是以千为单位,人工操作会麻木到崩溃。

二、解决方案

目前的基础办法就是使用python+selenium自动化来代替人工去操作,虽然效率比其他爬虫低,但是也防止被封IP的风险。也能满足项目的需求。准备工作,先从网站下载项目清单xls文件,里面会有对应的唯一识别码,就是编号。

三、写代码具体技术路线

1. init一个初始化函数,把selenium的驱动相关参数设置好。

2.get_html函数,实现打开浏览器登录进入需要爬取的主页面。

3.excel_to_dict函数,实现将前面准备的xls文件转为字典。

4.read_leftover函数,实现将尚未下载和下载失败的清单单独提取出来。

5.text_write函数,实现把页面上的文本内容保存到指定路径下的TXT文件中。

6.download函数,实现从主页面进入需要爬取的页面,完成导出后,再恢复初始状态。

7.run函数,是把所有功能函数驱动起来,实现爬虫过程。

8.讲以上函数定义到一个类里去,实现代码规范化。

四、具体代码如下:

  1. from selenium import webdriver
  2. from selenium.webdriver.common.by import By
  3. from selenium.webdriver.support.wait import WebDriverWait
  4. from selenium.webdriver.support import expected_conditions as EC
  5. from selenium.webdriver.common.action_chains import ActionChains
  6. import time
  7. import xlrd
  8. from xlutils.copy import copy
  9. import os
  10. class Zbph_Spider:
  11. def __init__(self):
  12. self.url = 'https://******'
  13. self.options = webdriver.FirefoxOptions()
  14. # 设置无头模式
  15. # self.options.add_argument("--headless")
  16. self.options.add_argument("--disable-gpu")
  17. # 隐身模式(无痕模式)
  18. self.driver = webdriver.Firefox(options=self.options)
  19. def get_html(self):
  20. # 调用WebDriver 对象的get方法 可以让浏览器打开指定网址
  21. self.driver.get(self.url)
  22. # 设置最大等待时长为 3秒,全局的。
  23. self.driver.implicitly_wait(15)
  24. # 最大化窗口
  25. self.driver.maximize_window()
  26. # 设置为本台电脑最大的分辨率,不然有头模式能运行,无头模式将无法运行。
  27. self.driver.set_window_rect(x=0, y=0, width=1920, height=1080)
  28. # 把弹窗点击确认让其消失
  29. self.driver.find_element(By.XPATH, '//span[contains(text(),"确 定")]').click()
  30. # 输入账号
  31. self.driver.find_element(By.XPATH, '//input[@id="txtLoginId"]').send_keys('****')
  32. # 输入密码
  33. self.driver.find_element(By.XPATH, '//input[@id="txtPassword"]').send_keys('*****')
  34. # 输入行政区代码
  35. self.driver.find_element(By.XPATH, '//input[@id="txtXzqdm"]').send_keys('522700')
  36. # 点击获取(手机)验证码,然后等待页面提示弹窗出来
  37. self.driver.find_element(By.XPATH, '//input[@id="btn_getValidCode"]').click()
  38. time.sleep(2)
  39. # 切换到alert弹窗并点击确定
  40. self.driver.switch_to.alert.accept()
  41. sj_yzm = input('请输入手机验证码:')
  42. time.sleep(0.5)
  43. self.driver.find_element(By.XPATH, '//input[@id="CheckCode"]').send_keys(sj_yzm)
  44. self.driver.find_element(By.XPATH, '//div/input[@value="登 录"]').click()
  45. time.sleep(3)
  46. # 把excel内容读取转为字典的函数
  47. def excel_to_dict(self, path):
  48. # 打开excel表格
  49. data_excel = xlrd.open_workbook(path)
  50. # 获取book中的第一sheet工作表法,返回一个xlrd.sheet.Sheet()对象
  51. table = data_excel.sheets()[0] # 通过索引顺序获取sheet
  52. keys = table.row_values(0)
  53. # 获取总行数
  54. rowNum = table.nrows
  55. # 获取总列数
  56. colNum = table.ncols
  57. # 需要读取的列,这里选择读取第二列,和第六列和第17列
  58. design_col_num = [0, 1, 5, 16]
  59. if rowNum <= 1:
  60. print("总行数小于1")
  61. else:
  62. r = []
  63. j = 1
  64. for i in range(rowNum - 1):
  65. s = {}
  66. # 从第二行获取对应的values值,方便下一步建立Keys使用
  67. values = table.row_values(j)
  68. for x in design_col_num:
  69. s[keys[x]] = values[x]
  70. r.append(s)
  71. j += 1
  72. return r
  73. # 把下载失败的项目清单写入excel
  74. def append_to_excel(self, words, row, column, filename):
  75. # 打开excel
  76. word_book = xlrd.open_workbook(filename)
  77. # 把xlrw对象变成xlwt对象,压入内存,使之可编辑
  78. new_work_book = copy(word_book)
  79. # 把可编辑的第一张表拿到
  80. new_sheet = new_work_book.get_sheet(0)
  81. # 设置开始写入的行数
  82. # 把文本写入对应的单元格内,参数分别是行、列和值,行列数从0起算。
  83. new_sheet.write(row + 1, column, words)
  84. # 从内存中把修改后的数据保存覆盖原来的文件
  85. new_work_book.save(filename)
  86. # print('下载状态追加写入成功!')
  87. # 读取仍需下载的项目清单。通过删掉下载状态为”下载成功“的记录实现,下一步只针对未下载或者下载失败的条目进行操作
  88. def read_leftover(self, list):
  89. i = 0
  90. while i < len(list):
  91. if list[i]['下载状态'] == '下载成功':
  92. del list[i]
  93. else:
  94. i += 1
  95. return list
  96. # 创建txt文件并并写入文本
  97. def text_write(self, name, msg, directory):
  98. full_path = directory + '\\TXT\\' + name + '.txt'
  99. file = open(full_path, 'w')
  100. file.write(msg)
  101. file.close()
  102. # 调用项目清单逐个下载坐标
  103. def download(self, xmmc, directory):
  104. # 点击左侧功能列表
  105. if xmmc['项目阶段'] == '验收项目':
  106. self.driver.find_element(By.XPATH, '//li/div[@title="项目验收阶段"]').click()
  107. time.sleep(0.5)
  108. self.driver.find_element(By.XPATH, '//span[text()="验收项目查询"]').click()
  109. time.sleep(0.5)
  110. else:
  111. self.driver.find_element(By.XPATH, '//li/div[@title="项目立项阶段"]').click()
  112. time.sleep(0.5)
  113. self.driver.find_element(By.XPATH, '//span[text()="立项项目查询"]').click()
  114. time.sleep(0.5)
  115. # 切入默认框架
  116. self.driver.switch_to.parent_frame()
  117. # 切入页面内嵌的第一层框架
  118. self.driver.switch_to.frame('u0')
  119. # 清除并输入新的备案编号
  120. self.driver.find_element(By.XPATH, '//*[@id="inp_xmbh"]').clear()
  121. self.driver.find_element(By.XPATH, '//*[@id="inp_xmbh"]').send_keys(xmmc['备案编号'])
  122. time.sleep(1)
  123. # 点击查询
  124. self.driver.find_element(By.XPATH, '//*[@id="btn_query"]').click()
  125. time.sleep(2.5)
  126. # 显性等待,等查询结果第一条是被查询对象,一直等到后面的条件成立(能定位)。
  127. WebDriverWait(self.driver, 20).until(
  128. EC.presence_of_element_located((By.XPATH, "//table/tbody/tr[1]/td[3][text()='" + xmmc['备案编号'] + "']")))
  129. # 定位到项目名称并双击
  130. element = self.driver.find_element(By.XPATH, '//*[@id="tlw_list_table"]/tbody/tr[1]/td[4]/input')
  131. ActionChains(self.driver).double_click(element).perform()
  132. time.sleep(1)
  133. # 等待新增耕地坐标按钮出现
  134. WebDriverWait(self.driver, 20).until(EC.element_to_be_clickable((By.XPATH, '//div[(text()="新增耕地坐标")]')))
  135. # 点击新增耕地坐标,使用JS脚本来点击,能解决需要点击的要素被遮挡无法点击的情况。
  136. xzgdzb = self.driver.find_element(By.XPATH, '//div[(text()="新增耕地坐标")]')
  137. self.driver.execute_script('arguments[0].click()', xzgdzb)
  138. time.sleep(3)
  139. # 切入内嵌的第二层框架
  140. self.driver.switch_to.frame('iframe_tab')
  141. time.sleep(0.2)
  142. dc_zz = self.driver.find_element(By.XPATH, '//div[(text()="导出")]')
  143. self.driver.execute_script('arguments[0].click()', dc_zz)
  144. time.sleep(0.5)
  145. # 切换到最新打开的标签页
  146. self.driver.switch_to.window(self.driver.window_handles[-1])
  147. try:
  148. # 获取页面文本
  149. words = self.driver.find_element(By.XPATH, '/html/body/pre').text
  150. # 调用写入txt函数把页面文本内容写入txt文件
  151. self.text_write(xmmc['备案编号'], words, directory)
  152. time.sleep(0.2)
  153. # 关闭当前标签页
  154. self.driver.close()
  155. print('---下载成功---')
  156. self.append_to_excel('下载成功', int(xmmc['序号']) - 1, 16, 'demo.xls')
  157. except:
  158. print('---下载失败---')
  159. self.append_to_excel('下载失败', int(xmmc['序号'] - 1), 16, 'demo.xls')
  160. self.driver.switch_to.window(self.driver.window_handles[0])
  161. # 切入页面内嵌的第一层框架
  162. self.driver.switch_to.frame('u0')
  163. # 点击返回
  164. self.driver.find_element(By.XPATH, '//div[text()="返回"]').click()
  165. time.sleep(0.5)
  166. # 把左侧列表返回默认状态
  167. if xmmc['项目阶段'] == '验收项目':
  168. # 退出框架,回到主页面
  169. self.driver.switch_to.parent_frame()
  170. self.driver.find_element(By.XPATH, '//li/div[@title="项目验收阶段"]').click()
  171. time.sleep(0.2)
  172. else:
  173. # 退出框架,回到主页面
  174. self.driver.switch_to.parent_frame()
  175. self.driver.find_element(By.XPATH, '//li/div[@title="项目立项阶段"]').click()
  176. time.sleep(0.2)
  177. # 驱动函数
  178. def run(self, path):
  179. # 调用读取xls函数读取项目清单
  180. list = self.excel_to_dict(path)
  181. new_list = self.read_leftover(list)
  182. # 打开、登录进入内部的页面
  183. self.get_html()
  184. # 调用下载函数根据项目清单依次下载所有项目坐标
  185. directory = os.path.dirname(path) # 提取xls表格所在文件夹
  186. i = 1
  187. numbers_sum = len(new_list)
  188. for Id in range(numbers_sum):
  189. print("{}/{} {}".format(i, numbers_sum, new_list[Id]['备案编号']))
  190. self.download(new_list[Id], directory)
  191. i += 1
  192. print(20*"-", '下载完毕', 20*"-")
  193. # 下载完毕后退出驱动
  194. self.driver.quit()
  195. # 主函数
  196. if __name__ == '__main__':
  197. # 调用读取xls函数读取项目清单
  198. Path = r"D:\demo\批量下载\demo.xls"
  199. spider = Zbph_Spider()
  200. spider.run(Path)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/409408
推荐阅读
相关标签
  

闽ICP备14008679号