for循环和多线程 + selenium

实例一

for循环

  1. # -*- coding: utf-8 -*-
  2.  
  3. """
  4. Datetime: 2019/6/22
  5. Author: Zhang Yafei
  6. Description:
  7. """
  8. import time
  9.  
  10. from selenium import webdriver
  11. from selenium.webdriver.chrome.options import Options
  12. from concurrent.futures import ThreadPoolExecutor
  13. import functools
  14.  
  15. chrome_options = Options()
  16. chrome_options.add_argument("--headless")
  17. chrome_options.add_argument('--disable-gpu')
  18.  
  19. def timeit(func):
  20. """
  21. 装饰器: 判断函数执行时间
  22. :param func:
  23. :return:
  24. """
  25.  
  26. @functools.wraps(func)
  27. def inner(*args, **kwargs):
  28. start = time.time()
  29. ret = func(*args, **kwargs)
  30. end = time.time() - start
  31. if end < 60:
  32. print(f'花费时间:\t{round(end, 2)}秒')
  33. else:
  34. min, sec = divmod(end, 60)
  35. print(f'花费时间\t{round(min)}分\t{round(sec, 2)}秒')
  36. return ret
  37.  
  38. return inner
  39.  
  40. class PolicyUrlDownload(object):
  41. """ 政策数据下载 """
  42.  
  43. def __init__(self, url, pages_num, output_file, a_xpath, headless: bool=True):
  44. self.url_list = [url.format(page) for page in range(1, pages_num+1)]
  45. self.output_file = output_file
  46. self.a_xpath = a_xpath
  47. if headless:
  48. self.driver = webdriver.Chrome(options=chrome_options)
  49. else:
  50. self.driver = webdriver.Chrome()
  51.  
  52. def start(self, page, url):
  53. with open(self.output_file, mode='a', encoding='utf-8') as file:
  54. print(f"make request to {url}")
  55. self.driver.get(url)
  56. titles = self.driver.find_elements_by_xpath(self.a_xpath)
  57. for title in titles:
  58. href = title.get_attribute('href')
  59. file.write(f'{page}\t{href}\n')
  60. print(f'{url} download completed')
  61.  
  62. def run(self):
  63. for page, url in enumerate(self.url_list):
  64. self.start(page+1, url)
  65. self.driver.close()
  66.  
  67. @timeit
  68. def main(setting):
  69. policy_data = PolicyUrlDownload(**setting)
  70. policy_data.run()
  71.  
  72. if __name__ == '__main__':
  73. start_time = time.time()
  74. print('######################## 开始下载 #########################')
  75.  
  76. # 多配置页面地址下载
  77. settings = [
  78. {
  79. 'output_file': '药品供应保障综合的管理.txt',
  80. 'url': 'http://cdsip.nhfpc.gov.cn/work/0-{}.html',
  81. 'pages_num': 8,
  82. 'a_xpath': '//div[@id="active0"]/ul/li/a'
  83. },
  84. {
  85. 'output_file': '药品供应保障综合的管理.txt',
  86. 'url': 'http://cdsip.nhfpc.gov.cn/policy/0-{}-0.html',
  87. 'pages_num': 9,
  88. 'a_xpath': '//div[@class="infoContent box-body"]/ul/li/a'
  89. }
  90. ]
  91.  
  92. for setting in settings:
  93. main(setting)
  94.  
  95. print('下载成功, 共花费时间 ', round(time.time() - start_time, 2), '秒')

结果

  1. 下载成功, 共花费时间 28.46

多线程

  1. # -*- coding: utf-8 -*-
  2.  
  3. """
  4. Datetime: 2019/6/22
  5. Author: Zhang Yafei
  6. Description:
  7. """
  8. import time
  9.  
  10. from selenium import webdriver
  11. from selenium.webdriver.chrome.options import Options
  12. from concurrent.futures import ThreadPoolExecutor
  13. import functools
  14.  
  15. chrome_options = Options()
  16. chrome_options.add_argument("--headless")
  17. chrome_options.add_argument('--disable-gpu')
  18.  
  19. def timeit(func):
  20. """
  21. 装饰器: 判断函数执行时间
  22. :param func:
  23. :return:
  24. """
  25.  
  26. @functools.wraps(func)
  27. def inner(*args, **kwargs):
  28. start = time.time()
  29. ret = func(*args, **kwargs)
  30. end = time.time() - start
  31. if end < 60:
  32. print(f'花费时间:\t{round(end, 2)}秒')
  33. else:
  34. min, sec = divmod(end, 60)
  35. print(f'花费时间\t{round(min)}分\t{round(sec, 2)}秒')
  36. return ret
  37.  
  38. return inner
  39.  
  40. class PolicyUrlDownload(object):
  41. """ 政策数据下载 """
  42.  
  43. def __init__(self, url, pages_num, output_file, a_xpath, headless: bool=True):
  44. self.url_list = [url.format(page) for page in range(1, pages_num+1)]
  45. self.output_file = output_file
  46. self.a_xpath = a_xpath
  47. if headless:
  48. self.driver = webdriver.Chrome(options=chrome_options)
  49. else:
  50. self.driver = webdriver.Chrome()
  51.  
  52. def start(self, page, url):
  53. with open(self.output_file, mode='a', encoding='utf-8') as file:
  54. print(f"make request to {url}")
  55. self.driver.get(url)
  56. titles = self.driver.find_elements_by_xpath(self.a_xpath)
  57. for title in titles:
  58. href = title.get_attribute('href')
  59. file.write(f'{page}\t{href}\n')
  60. print(f'{url} download completed')
  61.  
  62. def run(self):
  63. for page, url in enumerate(self.url_list):
  64. self.start(page+1, url)
  65. self.driver.close()
  66.  
  67. @timeit
  68. def main(setting):
  69. policy_data = PolicyUrlDownload(**setting)
  70. policy_data.run()
  71.  
  72. if __name__ == '__main__':
  73. start_time = time.time()
  74. print('######################## 开始下载 #########################')
  75.  
  76. # 多配置页面地址下载
  77. settings = [
  78. {
  79. 'output_file': '药品供应保障综合的管理.txt',
  80. 'url': 'http://cdsip.nhfpc.gov.cn/work/0-{}.html',
  81. 'pages_num': 8,
  82. 'a_xpath': '//div[@id="active0"]/ul/li/a'
  83. },
  84. {
  85. 'output_file': '药品供应保障综合的管理.txt',
  86. 'url': 'http://cdsip.nhfpc.gov.cn/policy/0-{}-0.html',
  87. 'pages_num': 9,
  88. 'a_xpath': '//div[@class="infoContent box-body"]/ul/li/a'
  89. }
  90. ]
  91. with ThreadPoolExecutor() as pool:
  92. pool.map(main, settings)
  93.  
  94. print('下载成功, 共花费时间 ', round(time.time() - start_time, 2), '秒')

结果

  1. 花费时间: 18.04

实例二

顺序执行

  1. # -*- coding: utf-8 -*-
  2. import os
  3. import time
  4. from concurrent.futures import ThreadPoolExecutor
  5. from hashlib import md5
  6.  
  7. from selenium import webdriver
  8. from selenium.webdriver.chrome.options import Options
  9. from selenium.webdriver.chrome.service import Service
  10. import numpy as np
  11.  
  12. class PolicyPageDownload(object):
  13. """ 政策数据下载 """
  14.  
  15. def __init__(self, file, dir_name, url_list):
  16. self.file = file
  17. self.dir_name = dir_name
  18. self.urls = url_list
  19. self.chrome_options = Options()
  20. self.chrome_options.add_argument("--headless")
  21. self.chrome_options.add_argument('--disable-gpu')
  22. self.driver = webdriver.Chrome(options=self.chrome_options)
  23. # self.driver = webdriver.Chrome()
  24.  
  25. def start(self, url):
  26. """
  27. 开始下载
  28. :param url:
  29. :return:
  30. """
  31. self.driver.get(url)
  32. response = self.driver.page_source
  33. print(f'make request to {url}')
  34. file_name = md5(bytes(url, encoding='utf-8')).hexdigest() + '.html'
  35. print('11111111111')
  36. with open(f'{self.dir_name}/{file_name}', 'w', encoding='utf-8') as file:
  37. file.write(response)
  38. print(f'{url} download completed')
  39.  
  40. def run(self):
  41. """ 入口函数 """
  42. [self.start(url) for url in self.urls]
  43. self.driver.quit()
  44.  
  45. def filter_urls(dir_name, urls):
  46. """
  47. 过滤url
  48. :param urls:
  49. :return:
  50. """
  51. encode_urls = [md5(bytes(url, encoding='utf-8')).hexdigest() + '.html' for url in urls]
  52. has_file = [file for file in os.listdir(dir_name) if os.path.getsize(os.path.join(dir_name, file)) > 0]
  53. encode_urls = set(encode_urls) - set(has_file)
  54. down_urls = list(
  55. filter(lambda url: md5(bytes(url, encoding='utf-8')).hexdigest() + '.html' in encode_urls, urls))
  56. print(f'共{len(set(urls))}\t已下载{len(set(has_file))}\t 还需下载{len(encode_urls)}')
  57. return down_urls
  58.  
  59. def run(url_list):
  60. policy = PolicyPageDownload(url_list=url_list, **setting)
  61. policy.run()
  62.  
  63. def main(file, dir_name):
  64. if not os.path.exists(dir_name):
  65. os.mkdir(dir_name)
  66. inputfile = open(file, 'r', encoding='utf-8')
  67. urls = [line.strip().split('\t')[1] for index, line in enumerate(inputfile)]
  68. if os.path.exists(dir_name):
  69. urls = filter_urls(dir_name, urls)
  70.  
  71. run(urls)
  72.  
  73. if __name__ == '__main__':
  74. start_time = time.time()
  75. setting = {
  76. 'file': '药品供应保障综合的管理.txt',
  77. 'dir_name': '药品供应保障综合的管理'
  78. }
  79. main(**setting)
  80.  
  81. print('下载成功, 共花费时间 ', round(time.time() - start_time, 2), '秒')

多线程

  1. # -*- coding: utf-8 -*-
  2. import os
  3. import time
  4. from concurrent.futures import ThreadPoolExecutor
  5. from hashlib import md5
  6.  
  7. from selenium import webdriver
  8. from selenium.webdriver.chrome.options import Options
  9. from selenium.webdriver.chrome.service import Service
  10. import numpy as np
  11.  
  12. class PolicyPageDownload(object):
  13. """ 政策数据下载 """
  14.  
  15. def __init__(self, file, dir_name, url_list):
  16. self.file = file
  17. self.dir_name = dir_name
  18. self.urls = url_list
  19. self.chrome_options = Options()
  20. self.chrome_options.add_argument("--headless")
  21. self.chrome_options.add_argument('--disable-gpu')
  22. self.driver = webdriver.Chrome(options=self.chrome_options)
  23. # self.driver = webdriver.Chrome()
  24.  
  25. def start(self, url):
  26. """
  27. 开始下载
  28. :param url:
  29. :return:
  30. """
  31. self.driver.get(url)
  32. response = self.driver.page_source
  33. print(f'make request to {url}')
  34. file_name = md5(bytes(url, encoding='utf-8')).hexdigest() + '.html'
  35. print('11111111111')
  36. with open(f'{self.dir_name}/{file_name}', 'w', encoding='utf-8') as file:
  37. file.write(response)
  38. print(f'{url} download completed')
  39.  
  40. def run(self):
  41. """ 入口函数 """
  42. [self.start(url) for url in self.urls]
  43. self.driver.quit()
  44.  
  45. def filter_urls(dir_name, urls):
  46. """
  47. 过滤url
  48. :param urls:
  49. :return:
  50. """
  51. encode_urls = [md5(bytes(url, encoding='utf-8')).hexdigest() + '.html' for url in urls]
  52. has_file = [file for file in os.listdir(dir_name) if os.path.getsize(os.path.join(dir_name, file)) > 0]
  53. encode_urls = set(encode_urls) - set(has_file)
  54. down_urls = list(
  55. filter(lambda url: md5(bytes(url, encoding='utf-8')).hexdigest() + '.html' in encode_urls, urls))
  56. print(f'共{len(set(urls))}\t已下载{len(set(has_file))}\t 还需下载{len(encode_urls)}')
  57. return down_urls
  58.  
  59. def run(url_list):
  60. policy = PolicyPageDownload(url_list=url_list, **setting)
  61. policy.run()
  62.  
  63. def main(file, dir_name):
  64. if not os.path.exists(dir_name):
  65. os.mkdir(dir_name)
  66. inputfile = open(file, 'r', encoding='utf-8')
  67. urls = [line.strip().split('\t')[1] for index, line in enumerate(inputfile)]
  68. if os.path.exists(dir_name):
  69. urls = filter_urls(dir_name, urls)
  70.  
  71. with ThreadPoolExecutor() as pool:
  72. pool.map(run, np.array_split(urls, 4))
  73.  
  74. if __name__ == '__main__':
  75. start_time = time.time()
  76. setting = {
  77. 'file': '药品供应保障综合的管理.txt',
  78. 'dir_name': '药品供应保障综合的管理'
  79. }
  80. main(**setting)
  81.  
  82. print('下载成功, 共花费时间 ', round(time.time() - start_time, 2), '秒')

运行结果

  1. # 50 for循环: 下载成功, 共花费时间 48.62 秒
  2. # 150 for循环: 共花费时间 150.22 秒
  3. # 150 多线程: 共花费时间 80.84 秒
  • 结论: 建立driver的花销较大,尽量创建一次,多次使用, 并发的话不能共用一个driver,必须重新创建
  • 使用技巧总结:创建多个线程,个数最好和cpu个数相同,每个线程创建一个driver

  

selenium实现并发的更多相关文章

  1. 使用jenkins pipeline,并发selenium测试 --- 你值得了解

    一.契机 相信很多使用selenium进行UI测试,再对接jenkins时,都是简单的在jenkins上将命令输入就完事了. 但是,相信你一定会遇到以下问题: 1.你需要同时跑不同文件或不同类的用例, ...

  2. selenium 并发执行测试用例

    转帖: 要想多线程并发的运行WebDriver,必须同时满足2个条件,首先你的测试程序是多线程,其次需要用到Selenium Server(selenium-server-standalone-XXX ...

  3. Selenium & Webdriver 远程测试和多线程并发测试

    Selenium & Webdriver 远程测试和多线程并发测试 Selenium Webdriver自动化测试,初学者可以使用selenium ide录制脚本,然后生成java程序导入ec ...

  4. selenium从入门到应用 - 8,selenium+testNG实现多线程的并发测试

    本系列所有代码 https://github.com/zhangting85/simpleWebtest本文将介绍一个Java+TestNG+Maven+Selenium的web自动化测试脚本环境下s ...

  5. Selenium 2 & WebDriver &多线程 并发

    我用的是Selenium2,至于它的背景和历史就不赘述了.Selenium2也叫WebDriver.下面讲个例子,用WebDriver+java来写个自动化测试的程序.(如果能用firefox去测试的 ...

  6. selenium grid解决多台电脑进行并发执行测试脚本

    1 两台计算机,一台计算机既做HUB,又做Node 机器A设置HUB的步骤: 1 运行---输入cmd 2 输入: cd c:/ 3  输入: java -jar selenium-server-st ...

  7. selenium 常见面试题以及答案(Java版)

    1.怎么 判断元素是否存在? 判断元素是否存在和是否出现不同, 判断是否存在意味着如果这个元素压根就不存在, 就会抛出NoSuchElementException 这样就可以使用try catch,如 ...

  8. 搭建selenium grid简单配置

    1.使用selenium提供的服务端独立jar包 :服务端.客户端都是运行于java7环境. 2.启动hub: hub配置文件如下: Java -jar selenium-server-standal ...

  9. 关于selenium的CI、框架……

    这段时间除了项目测试外,主要在做web自动化的事情,大致总结一下吧,总体的设计模式pageobject+pagefactory+testng的数据驱动,项目用maven来构建,使用jenkins集成, ...

随机推荐

  1. 设计风格之REST

    一.简介 REST简介 REST 是英文 representational state transfer(表象性状态转变)或者表述性状态转 移;Rest 是 web 服务的一种架构风格;使用 HTTP ...

  2. 筛选Table.SelectRows-日期与时间(Power Query 之 M 语言)

    数据源: 包含日期与时间的任意数据 目标: 对日期与时间进行筛选 M公式: = Table.SelectRows( 表,筛选条件) 筛选条件: 等于:each [日期列] = #date(年,月,日) ...

  3. 学习型的“文山表海无限发展公司”——《Office妖精是怎样炼成的》续1

    本篇无故事情节版:https://www.cnblogs.com/officeplayer/p/14841590.html <Office妖精是怎样炼成的>http://blog.sina ...

  4. 自动化集成:Pipeline流水语法详解

    前言:该系列文章,围绕持续集成:Jenkins+Docker+K8S相关组件,实现自动化管理源码编译.打包.镜像构建.部署等操作:本篇文章主要描述Pipeline流水线用法. 一.Webhook原理 ...

  5. 以太网/ IPV4/IPV6包头,TCP包头格式回顾

    问题:以太网数据包,承载的数据内容大小46~1500字节,是如何来的? 以太网数据包结构  以太网协议规定最小链路层数据包(帧)为64字节,其中以太网首部+尾部共计18字节(源/目的MAC12字节:上 ...

  6. vue+uniapp实现多任务并发下载文件 | 断点续下, 任务列表, 多任务并发限制

    一.插件简介 zhimi-downloadManager(智密 - 多任务下载管理插件)是一个支持多任务多并发下载,支持多/单任务管理,并且实时反馈任务下载进度的uniapp原生插件.平台支持:And ...

  7. AcWing1264. 动态求连续区间和 (线段树做法)

    1.题目 给定 n 个数组成的一个数列,规定有两种操作,一是修改某个元素,二是求子数列 [a,b] 的连续和. 输入格式 第一行包含两个整数 n 和 m,分别表示数的个数和操作次数. 第二行包含 n ...

  8. c++指针函数和函数指针概述

    欢迎指正 代码写的不够规范: 目的是缩短文章篇幅,实际中请注意 阅读完本文, 你一定能判断和写出:指针函数和函数指针. 0.结论 A.指针函数: 函数的返回值是指针类型 B.函数指针: 函数名是一个指 ...

  9. 【LeetCode】592. Fraction Addition and Subtraction 解题报告(Python)

    [LeetCode]592. Fraction Addition and Subtraction 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id: fuxuem ...

  10. python学习第四天:python基础(字符编码和乱码到底咋回事儿)

    字符编码 这得从字符编码开始说起: 字符串也是一种数据类型,但是,字符串比较特殊的是还有一个编码问题.因为计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理. 最早的计算机在设计时采 ...