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

一、项目需求

在一个业务网站有可以一个个打开有相关内容的文本,需要逐个保存为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.讲以上函数定义到一个类里去,实现代码规范化。

四、具体代码如下:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains
import time
import xlrd
from xlutils.copy import copy
import os


class Zbph_Spider:
    def __init__(self):
        self.url = 'https://******'
        self.options = webdriver.FirefoxOptions()
        # 设置无头模式
        # self.options.add_argument("--headless")
        self.options.add_argument("--disable-gpu")
        # 隐身模式(无痕模式)
        self.driver = webdriver.Firefox(options=self.options)

    def get_html(self):
        # 调用WebDriver 对象的get方法 可以让浏览器打开指定网址
        self.driver.get(self.url)
        # 设置最大等待时长为 3秒,全局的。
        self.driver.implicitly_wait(15)
        # 最大化窗口
        self.driver.maximize_window()
        # 设置为本台电脑最大的分辨率,不然有头模式能运行,无头模式将无法运行。
        self.driver.set_window_rect(x=0, y=0, width=1920, height=1080)
        # 把弹窗点击确认让其消失
        self.driver.find_element(By.XPATH, '//span[contains(text(),"确 定")]').click()
        # 输入账号
        self.driver.find_element(By.XPATH, '//input[@id="txtLoginId"]').send_keys('****')
        # 输入密码
        self.driver.find_element(By.XPATH, '//input[@id="txtPassword"]').send_keys('*****')
        # 输入行政区代码
        self.driver.find_element(By.XPATH, '//input[@id="txtXzqdm"]').send_keys('522700')
        # 点击获取(手机)验证码,然后等待页面提示弹窗出来
        self.driver.find_element(By.XPATH, '//input[@id="btn_getValidCode"]').click()
        time.sleep(2)
        # 切换到alert弹窗并点击确定
        self.driver.switch_to.alert.accept()
        sj_yzm = input('请输入手机验证码:')
        time.sleep(0.5)
        self.driver.find_element(By.XPATH, '//input[@id="CheckCode"]').send_keys(sj_yzm)
        self.driver.find_element(By.XPATH, '//div/input[@value="登  录"]').click()
        time.sleep(3)

    # 把excel内容读取转为字典的函数
    def excel_to_dict(self, path):
        # 打开excel表格
        data_excel = xlrd.open_workbook(path)
        # 获取book中的第一sheet工作表法,返回一个xlrd.sheet.Sheet()对象
        table = data_excel.sheets()[0]  # 通过索引顺序获取sheet
        keys = table.row_values(0)
        # 获取总行数
        rowNum = table.nrows
        # 获取总列数
        colNum = table.ncols
        # 需要读取的列,这里选择读取第二列,和第六列和第17列
        design_col_num = [0, 1, 5, 16]
        if rowNum <= 1:
            print("总行数小于1")
        else:
            r = []
            j = 1
            for i in range(rowNum - 1):
                s = {}
                # 从第二行获取对应的values值,方便下一步建立Keys使用
                values = table.row_values(j)
                for x in design_col_num:
                    s[keys[x]] = values[x]
                r.append(s)
                j += 1
        return r

    # 把下载失败的项目清单写入excel
    def append_to_excel(self, words, row, column, filename):
        # 打开excel
        word_book = xlrd.open_workbook(filename)
        # 把xlrw对象变成xlwt对象,压入内存,使之可编辑
        new_work_book = copy(word_book)
        # 把可编辑的第一张表拿到
        new_sheet = new_work_book.get_sheet(0)
        # 设置开始写入的行数
        # 把文本写入对应的单元格内,参数分别是行、列和值,行列数从0起算。
        new_sheet.write(row + 1, column, words)
        # 从内存中把修改后的数据保存覆盖原来的文件
        new_work_book.save(filename)
        # print('下载状态追加写入成功!')

    # 读取仍需下载的项目清单。通过删掉下载状态为”下载成功“的记录实现,下一步只针对未下载或者下载失败的条目进行操作
    def read_leftover(self, list):
        i = 0
        while i < len(list):
            if list[i]['下载状态'] == '下载成功':
                del list[i]
            else:
                i += 1
        return list

    # 创建txt文件并并写入文本
    def text_write(self, name, msg, directory):
        full_path = directory + '\\TXT\\' + name + '.txt'
        file = open(full_path, 'w')
        file.write(msg)
        file.close()

    # 调用项目清单逐个下载坐标
    def download(self, xmmc, directory):
        # 点击左侧功能列表
        if xmmc['项目阶段'] == '验收项目':
            self.driver.find_element(By.XPATH, '//li/div[@title="项目验收阶段"]').click()
            time.sleep(0.5)
            self.driver.find_element(By.XPATH, '//span[text()="验收项目查询"]').click()
            time.sleep(0.5)
        else:
            self.driver.find_element(By.XPATH, '//li/div[@title="项目立项阶段"]').click()
            time.sleep(0.5)
            self.driver.find_element(By.XPATH, '//span[text()="立项项目查询"]').click()
            time.sleep(0.5)
        # 切入默认框架
        self.driver.switch_to.parent_frame()
        # 切入页面内嵌的第一层框架
        self.driver.switch_to.frame('u0')
        # 清除并输入新的备案编号
        self.driver.find_element(By.XPATH, '//*[@id="inp_xmbh"]').clear()
        self.driver.find_element(By.XPATH, '//*[@id="inp_xmbh"]').send_keys(xmmc['备案编号'])
        time.sleep(1)
        # 点击查询
        self.driver.find_element(By.XPATH, '//*[@id="btn_query"]').click()
        time.sleep(2.5)
        # 显性等待,等查询结果第一条是被查询对象,一直等到后面的条件成立(能定位)。
        WebDriverWait(self.driver, 20).until(
            EC.presence_of_element_located((By.XPATH, "//table/tbody/tr[1]/td[3][text()='" + xmmc['备案编号'] + "']")))
        # 定位到项目名称并双击
        element = self.driver.find_element(By.XPATH, '//*[@id="tlw_list_table"]/tbody/tr[1]/td[4]/input')
        ActionChains(self.driver).double_click(element).perform()
        time.sleep(1)
        # 等待新增耕地坐标按钮出现
        WebDriverWait(self.driver, 20).until(EC.element_to_be_clickable((By.XPATH, '//div[(text()="新增耕地坐标")]')))
        # 点击新增耕地坐标,使用JS脚本来点击,能解决需要点击的要素被遮挡无法点击的情况。
        xzgdzb = self.driver.find_element(By.XPATH, '//div[(text()="新增耕地坐标")]')
        self.driver.execute_script('arguments[0].click()', xzgdzb)
        time.sleep(3)
        # 切入内嵌的第二层框架
        self.driver.switch_to.frame('iframe_tab')
        time.sleep(0.2)
        dc_zz = self.driver.find_element(By.XPATH, '//div[(text()="导出")]')
        self.driver.execute_script('arguments[0].click()', dc_zz)
        time.sleep(0.5)
        # 切换到最新打开的标签页
        self.driver.switch_to.window(self.driver.window_handles[-1])
        try:
            # 获取页面文本
            words = self.driver.find_element(By.XPATH, '/html/body/pre').text
            # 调用写入txt函数把页面文本内容写入txt文件
            self.text_write(xmmc['备案编号'], words, directory)
            time.sleep(0.2)
            # 关闭当前标签页
            self.driver.close()
            print('---下载成功---')
            self.append_to_excel('下载成功', int(xmmc['序号']) - 1, 16, 'demo.xls')
        except:
            print('---下载失败---')
            self.append_to_excel('下载失败', int(xmmc['序号'] - 1), 16, 'demo.xls')

        self.driver.switch_to.window(self.driver.window_handles[0])
        # 切入页面内嵌的第一层框架
        self.driver.switch_to.frame('u0')
        # 点击返回
        self.driver.find_element(By.XPATH, '//div[text()="返回"]').click()
        time.sleep(0.5)
        # 把左侧列表返回默认状态
        if xmmc['项目阶段'] == '验收项目':
            # 退出框架,回到主页面
            self.driver.switch_to.parent_frame()
            self.driver.find_element(By.XPATH, '//li/div[@title="项目验收阶段"]').click()
            time.sleep(0.2)
        else:
            # 退出框架,回到主页面
            self.driver.switch_to.parent_frame()
            self.driver.find_element(By.XPATH, '//li/div[@title="项目立项阶段"]').click()
            time.sleep(0.2)

    # 驱动函数
    def run(self, path):
        # 调用读取xls函数读取项目清单
        list = self.excel_to_dict(path)
        new_list = self.read_leftover(list)
        # 打开、登录进入内部的页面
        self.get_html()
        # 调用下载函数根据项目清单依次下载所有项目坐标
        directory = os.path.dirname(path)  # 提取xls表格所在文件夹
        i = 1
        numbers_sum = len(new_list)
        for Id in range(numbers_sum):
            print("{}/{}  {}".format(i, numbers_sum, new_list[Id]['备案编号']))
            self.download(new_list[Id], directory)
            i += 1
        print(20*"-", '下载完毕', 20*"-")
        # 下载完毕后退出驱动
        self.driver.quit()

# 主函数
if __name__ == '__main__':
    # 调用读取xls函数读取项目清单
    Path = r"D:\demo\批量下载\demo.xls"
    spider = Zbph_Spider()
    spider.run(Path)

  • 2
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 这个问题似乎被编码了。但是回答上面的提问,关于Python Selenium爬虫的示例,下面是可能的回答: Python Selenium爬虫的示例包括: - 模拟登录网站并抓取信息,例如抓取用户账户数据或者其他数据 - 爬取页面内容,例如抓取产品信息、天气预报、新闻内容等 - 自动填写表单,例如自动填写调查问卷,自动提交订阅表格等 - 自动化测试网页,例如测试UI页面呈现、点击、跳转等 - 对特定网站进行批量操作,例如对在线商店进行批量下单操作,自动定时发送邮件等 PythonSelenium的结合,使得实现这些功能变得更加容易。通过Selenium的API接口可以自动化Web操作,并使用Python脚本来控制Selenium实例,实现各种爬取任务。 ### 回答2: Python Selenium爬虫是一种基于Python脚本语言和Selenium驱动的网页爬取工具,可以通过模拟网页浏览器的操作,自动化地爬取网页数据。Python Selenium爬虫具有速度快、难以被反爬、可视化程度高等优点,因此深受开发者的青睐。 下面以一个简单的Python Selenium爬虫实例来说明其使用方法: 1.准备工作 首先,需要在自己的电脑上安装Python环境和Selenium包。具体步骤如下: (1)安装Python环境:去官网下载对应的Python版本,并按照提示安装即可。 (2)安装Selenium包:在命令行输入“pip install selenium”,即可安装Selenium包。 (3)下载浏览器驱动:Selenium支持多种浏览器,因此需要下载对应的驱动。以Chrome浏览器为例,在http://chromedriver.storage.googleapis.com/index.html下载对应版本的驱动,并保存到本地。 2.代码实现 该实例的任务是爬取豆瓣电影Top250的电影名称和评分,并将其输出到控制台。 (1)导入必要的库:代码中需要导入selenium、time、openpyxl等库,以便实现相关操作。 (2)获取网页源代码:首先需要启动一个chrome浏览器并访问豆瓣电影Top250的页面。Selenium可以模拟人的操作,因此可以使用get()方法打开指定的网页。 (3)解析HTML页面:获取网页源代码后,使用BeautifulSoup库对HTML页面进行解析,以便后续提取所需数据。 (4)定位所需数据:通过分析网页源代码,可以找到电影名称和评分所在的标签位置。使用Selenium的find_elements_by_xpath()方法定位指定的元素并提取数据。 (5)输出结果:将提取的电影名称和评分输出到控制台。 3.代码示例 以下是该实例的完整代码示例: ``` from selenium import webdriver from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By from bs4 import BeautifulSoup import time # 启动Chrome浏览器 driver = webdriver.Chrome(executable_path='./chromedriver.exe') driver.get('https://movie.douban.com/top250') # 等待页面加载完成 wait = WebDriverWait(driver, 5) wait.until(EC.presence_of_element_located((By.CLASS_NAME, 'grid_view'))) # 解析HTML页面 html = driver.page_source soup = BeautifulSoup(html, 'lxml') # 查找电影名称和评分标签 movies = soup.find_all('div', class_='hd') rates = soup.find_all('span', class_='rating_num') # 输出结果 for movie, rate in zip(movies, rates): print(movie.a.span.text, rate.text) # 关闭浏览器 driver.quit() ``` 通过以上代码实现,我们就可以快捷地获取豆瓣电影Top250的电影名称和评分数据,并且还可以将其输出到控制台中,方便后续数据处理和分析。不过要注意,爬虫要遵守相关法规和规范,不要非法地获取、利用网站数据,以免触犯法律。 ### 回答3: Python Selenium是一个强大的Web自动化测试工具,可以模拟真实用户的行为,并完成一系列的操作,如自动化登录,爬取数据等。在Python爬虫中,Selenium也有着非常广泛的应用,在数据采集与数据分析等领域都有着不可替代的作用。 Python Selenium爬虫实例的基本步骤如下: 1. 安装Selenium模块和相应浏览器驱动 Selenium需要安装相应的模块和浏览器驱动才能正确运行。比如,如果我们想在Chrome上运行Selenium,就需要安装selenium模块和Chrome浏览器驱动。 2. 打开网页 使用Selenium打开需要爬取的页面,通过访问页面URL地址,拿到页面内容。 3. 查找元素 通过查找网页源代码中的HTML元素,找到需要爬取的数据所在的位置。 4. 提取数据 通过Selenium提供的方法,获取所需数据,并进行二次处理以获取更为精确的数据。 5. 数据存储 将获取的数据存储在本地文件或数据库中,便于后续的数据处理和分析。 举个例子,如果我们想通过Selenium爬取百度页面的搜索结果,可以按照以下步骤进行: 1. 安装Selenium和Chrome浏览器驱动 ``` pip install selenium ``` 同时也需要下载相应版本的Chrome驱动并解压缩,然后将驱动文件所在路径加入环境变量。 2. 打开网页 ```python from selenium import webdriver # 指定浏览器驱动的路径 driver = webdriver.Chrome('path/to/chromedriver') # 使用get方法访问要爬取的百度页面 driver.get('https://www.baidu.com') ``` 3. 查找元素 我们想要爬取的是搜索结果列表,其在百度页面中的HTML代码如下: ```html <div id="content_left"> <!-- 搜索结果列表 --> <div class="result">...</div> <!-- 搜索结果项 --> <div class="result">...</div> <div class="result">...</div> ... </div> ``` 我们可以使用Selenium的find_elements_by_xpath方法查找元素。XPath语法是一种在XML文档中查找信息的语言,也可以用在HTML文档中。以下是示例代码: ```python # 使用XPath查找搜索结果列表 result_list = driver.find_elements_by_xpath('//div[@id="content_left"]/div[@class="result"]') ``` 4. 提取数据 从搜索结果列表中获取每个搜索结果的标题和链接,并将数据存储在本地文件中: ```python # 遍历搜索结果列表,获取结果标题和链接 for res in result_list: # 获取搜索结果标题 title = res.find_element_by_xpath('.//h3/a').text # 获取搜索结果链接 link = res.find_element_by_xpath('.//h3/a').get_attribute('href') # 将搜索结果写入文件 with open('results.txt', 'a', encoding='utf-8') as f: f.write(title+'\t'+link+'\n') ``` 5. 数据存储 上述代码将搜索结果存储在名为“results.txt”的文件中。 其他常见的Python Selenium爬虫实例包括: - 爬取动态页面 通过Selenium模拟用户在网页上的操作,如下拉滚动条等,从而爬取动态页面上的数据。 - 自动登录爬虫 利用Selenium实现自动登录,避免个人信息被盗,也方便持续爬取一些需要登录后才能访问的数据。 - 爬取验证码 自动识别验证码,提高爬虫的成功率。 总之,Python Selenium爬虫实例应用非常广泛,我们可以根据具体的需求随时调整实现方式,获取更多更有用的数据,同时也需要注意把握好爬虫的合法性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值