|
目录前言一、Selenium是什么二、Python安装Selenium1、安装Selenium第三方库2、下载浏览器驱动3、使用Python来打开浏览器三、Selenium的初始化四、Selenium获取网页元素4.1、获取元素的实用方法1、模糊匹配获取元素&联合多个样式2、使用拉姆达表达式3、加上睡眠时间,增加容错4、合理利用树形结构4.2、获取网页元素失败怎么办?1、确保4.1的方法都使用正确!!2、检查我们的代码,获取的那个代码,是否有问题3、iframe的问题4、网页跳转的问题五、Selenium点击元素的方法在Selenium中触发点击事件(最常用的三种方法)1、使用click()方法:2、使用JavaScript执行点击事件:3、使用ActionChains类:另外四种(不常用)4、使用send_keys(Keys.RETURN)模拟回车键:5、使用submit()方法提交表单:6、使用JavaScript修改元素属性:7、使用Robot类模拟物理点击:六、Selenium+browsermob-proxy获取网络请求1.下载browsermob-proxy.bat 2.安装python模块browsermob-proxy3、编写代码前言在实习的时候,需要做一些爬虫,所以就接触到了Selenium再开始就使用调用接口,所以需要去逆向找RSA加密算法的key,或者其他加密的东西后面发现,不管是黑猫还是白猫,抓到老鼠就是好猫逆向网页这玩意,我是真不懂,又没有兴趣去研究所以还是大道至简,直接用Selenium抓取网页数据吧,简单方便!一、Selenium是什么Selenium是一个用于自动化web应用程序测试的工具。它提供了一组工具和库,可以用多种编程语言(如Java、Python、C#等)编写测试脚本,模拟用户在浏览器中的行为,如点击链接、填写表单、提交数据等。Selenium可以在各种浏览器上运行,包括Chrome、Firefox、Safari等,它还可以与其他测试框架和工具集成,帮助开发人员和测试人员自动化执行各种测试任务,提高测试效率和质量。官网:SeleniumSeleniumautomatesbrowsers.That'sit!https://www.selenium.dev/Selenium是支持多种语言的这里只说关于Python的二、Python安装Selenium1、安装Selenium第三方库我习惯用4.6低版本的#换源pipconfigsetglobal.index-urlhttps://pypi.tuna.tsinghua.edu.cn/simple#安装我这个版本pipinstallselenium==4.6.0#安装默认最新版本pipinstallselenium下载Selenium后,我们需要他来打开浏览器,但是Selenium需要有浏览器驱动,才可以打开浏览器2、下载浏览器驱动下面是Selenium目前支持的浏览器这里只介绍如何下载谷歌浏览器的驱动,因为我只用过谷歌浏览器的先确定自己的谷歌浏览器的版本打开谷歌浏览器,输入地址:chrome://settings/help可以查看自己的版本:选择对应版本号的驱动版本下载地址:https://chromedriver.storage.googleapis.com/index.html这里记录下最新版本谷歌驱动器下载地址:https://googlechromelabs.github.io/chrome-for-testing/ 我这里打包上传了几个版本的驱动,有需要的,自取:2024-5-最近几个版本的谷歌浏览器驱动.zip-蓝奏云文件大小:46.9M|https://wwm.lanzout.com/iNYDd20cs3ef3、使用Python来打开浏览器一般情况下,一些博主推荐存放在python的安装路径那个只能说方便了我们自己使用,可以快速跑代码demo但是,当我们需要项目打包,在其他电脑上运行的时候,浏览器驱动放哪里?这就是一个问题!所以我们需要实现设置好驱动的路径我就是直接放在D盘了运行代码demofromseleniumimportwebdriver#设置Chrome浏览器驱动程序的路径chrome_driver_path="D:\\chromedriver.exe"#初始化Chrome浏览器browser=webdriver.Chrome(executable_path=chrome_driver_path)#打开百度网页browser.get("https://www.baidu.com")#这里可以编写其他与页面交互的代码#关闭浏览器browser.quit()当我们看见百度网页后,浏览器就会关闭,这样就说明我们设置完成了三、Selenium的初始化当我们创建浏览器驱动对象的时候,他会创建一个新的干净的浏览器,来供我们使用fromseleniumimportwebdriver#设置Chrome浏览器驱动程序的路径chrome_driver_path="D:\\chromedriver.exe"#初始化Chrome浏览器browser=webdriver.Chrome(executable_path=chrome_driver_path)所以,我们在浏览器上设置的东西,也可以通过代码实现设置好比如:浏览器下载文件后,下载的地址设置浏览器是否加载图片浏览器是否禁用JS浏览器是否使用隐私模式浏览器是否使用缓存等等...因此,我们可以实现封装一个类,来实现浏览器的初始化我写的一个简单类,可以通过json文件来修改参数比如:获取驱动的路径(在打包后,我们的驱动也需要在生产环境中,让程序可以找到,这时候我们灵活修改)是否加载图片是否使用缓存等等下面的代码,只适用4.8以下低版本的哟~#-*-coding:utf-8-*-#@Author:pan#@Description:获取浏览器驱动模块#@Date:2024年5月25日17:53:17'''##无界面化.#chrome_opt.add_argument('--headless')##配合上面的无界面化.#chrome_opt.add_argument('--disable-gpu')#设置窗口大小,窗口大小会有影响.#chrome_opt.add_argument('--window-size=1366,768')#不加载图片,提升速度#chrome_opt.add_argument('--blink-settings=imagesEnabled=false')##使用沙盒模式运行#chrome_opt.add_argument("--no-sandbox")#远程操控#chromedriver=webdriver.Remote(_chromedriverUrl,options=chrome_opt)#自动接受警告和对话框#chrome_opt.add_argument('--auto-open-devtools-for-tabs')#忽略SSL错误:对于测试环境中自签名证书的站点。chrome_opt.add_argument('--ignore-certificate-errors')#chromedriver.set_page_load_timeout(30)#设置页面加载超时时间#chromedriver.execute_cdp_cmd("Page.setCacheDisabled",{"cacheDisabled":True})#禁用缓存#自定义Chrome的数据存储目录,用于持久化Cookies、存储等。#chrome_opt.add_experimental_option('prefs',{'profile.default_content_settings.popups':0,#'download.default_directory':'/path/to/download'})##创建一个临时目录来存储浏览器会话的数据#user_data_dir="/path/to/temp/dir"#替换为你希望存储临时数据的路径#ifos.path.exists(user_data_dir):#shutil.rmtree(user_data_dir)#如果目录已存在,则删除它#os.makedirs(user_data_dir)#创建新的临时目录##chrome_opt.add_argument(f"user-data-dir={user_data_dir}")#设置代理#chrome_opt.add_argument('--proxy-server=http://ip:port')#chrome_opt.add_argument('--proxy-server=http://127.0.0.1:8888')#启动无痕模式#chrome_opt.add_argument('--incognito')#禁用扩展#chrome_opt.add_argument('--disable-extensions')#禁用JS#chrome_opt.add_argument('--disable-javascript')#用户代理设置:模拟不同的浏览器或设备访问。#chrome_opt.add_argument('--user-agent=Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/58.0.3029.110Safari/537.3')'''importtimeimportjsonimportosfromdataclassesimportdataclass,asdictfromseleniumimportwebdriver@dataclassclassWebDriveConf:"""浏览器驱动配置"""chromedriver_url:str='D:\\chromedriver.exe'#浏览器驱动路径user_data_dir:str='D:\\webDriverTempDir'#存储临时数据的路径is_use_cache:int=0#是否使用缓存is_load_page:int=1#是否加载页面is_load_img:int=0#是否加载图片is_ignore_certificate:int=1#是否忽略证书is_incognito:int=1#是否启动无痕模式defto_dict(self)->dict:"""返回配置信息的JSON格式表示Returns:dict:配置信息的JSON格式表示"""returnasdict(self)defread_json_config(self,file_path:str)->dict:"""从JSON文件中读取配置信息并返回字典Args:file_path(str):JSON文件路径Returns:dict:包含配置信息的字典"""#检查文件是否存在ifnotos.path.exists(file_path):#如果文件不存在,则创建一个包含默认配置信息的JSON文件withopen(file_path,"w")asfile:json.dump(self.to_dict(),file,indent=4)#读取配置文件withopen(file_path,"r")asfile:config_dict=json.load(file)returnconfig_dictdefwrite_json_config(self,config_dict:dict,file_path:str):"""将配置信息写入JSON文件Args:config_dict(dict):包含配置信息的字典file_path(str):JSON文件路径"""withopen(file_path,"w")asfile:json.dump(config_dict,file,indent=4)classChromeWebDriver:def__init__(self,conf:WebDriveConf):self.conf=confself.chrome_opt=webdriver.ChromeOptions()self.chrome_opt.add_argument('--user-data-dir='+self.conf.user_data_dir)#判断是否使用缓存(如果不使用缓存,则删除缓存文件)ifnotself.conf.is_use_cache:ifos.path.exists(self.conf.user_data_dir):#删除这个文件夹importshutilshutil.rmtree(self.conf.user_data_dir)#判断是否有文件夹ifnotos.path.exists(self.conf.user_data_dir)s.makedirs(self.conf.user_data_dir)#无界面化ifnotself.conf.is_load_page:self.chrome_opt.add_argument('--headless')#是否加载图片ifnotself.conf.is_load_img:self.chrome_opt.add_argument('--blink-settings=imagesEnabled=false')#是否忽略证书ifself.conf.is_ignore_certificate:self.chrome_opt.add_argument('--ignore-certificate-errors')#启动无痕模式ifself.conf.is_incognito:self.chrome_opt.add_argument('--incognito')#创建ChromeWebDriver实例self.chromedriver=webdriver.Chrome(executable_path=self.conf.chromedriver_url,options=self.chrome_opt)if__name__=='__main__':#创建WebDriveConf实例并解包配置信息web_driver_conf=WebDriveConf(**WebDriveConf().read_json_config("web_driver_conf.json"))#创建ChromeWebDriver实例chrome_web_driver=ChromeWebDriver(web_driver_conf)#打开网页chrome_web_driver.chromedriver.get("https://www.bilibili.com/?spm_id_from=333.788.0.0")time.sleep(10)chrome_web_driver.chromedriver.quit()四、Selenium获取网页元素首先,我们需要了解网页的结构,打开网页按F12,或者右键页面,然后点击【检查】即可看见到我们的开发者界面就可以html代码了,那个元素就想树形图一样的排列,所以我们获取的方法有很多种现在默认你有前端的基础,了解HTML当我们打开了网页,我们就可以获取网页上的任何东西当然,一般我们只需要获取网页上的一些数据信息,文本内容比如:获取元素中的文本内容#通过XPath选择元素element=driver.find_element_by_xpath("//h1")#获取元素中的文本text=element.textprint("元素中的文本是:",text)获取元素的属性内容#通过XPath选择元素element=driver.find_element_by_xpath("//h1")#获取元素中的class内容class_content=element.get_attribute("class")print("元素中的class内容是:",class_content)但是,最关键的一点是我们如何获取这些元素呢?你如何确定最后的element是我们想要的那一个呢?Selenium有很多元素筛选方法,通过class、id等等进行筛选下面就是常见方法但是还是最推荐用xpath可以直接下图方法使用这个来获取这个元素的路径但是我更喜欢自己手动找元素!4.1、获取元素的实用方法打开网页后,我们就需要和里面的元素进行交互,所以我们要获取1、模糊匹配获取元素&联合多个样式main_line_list=chromedriver.find_elements(By.XPATH,f"//span[@class='fancytree-title'andcontains(@title,'干线')]")这里既筛选了class中的内容,又筛选了这个span标签里面的文本信息其实,一般情况下,我们可以直接模糊匹配内容就足够了!也就是直接使contains!!!所以这就是为什么建议使用xpath了2、使用拉姆达表达式这样可以更加直观的看出代码含义element=WebDriverWait(chromedriver,timeout=10). until(lambdad:d.find_element(By.ID,"tree-input"))3、加上睡眠时间,增加容错当浏览器点击了一些东西之后,他需要加载或者跳转网页所以我们需要让程序睡眠一下,增加容错尤其是,我实习的那里,那些电脑都是老古董,时不时就抽风,卡顿...chrome_web_driver.chromedriver.find_element(By.XPATH,"//span[text()='重置密码']").click()time.sleep(2)4、合理利用树形结构有时候,我们定位一个元素,往往会有多个重复的元素我们可以先获取他的祖先元素,在祖先元素的基础上,再进行获取!chromedriver.find_element(By.ID,'colid-1934886344377413').find_element(By.CLASS_NAME,"suffix-group")5、获取多个元素当我们需要批量操作时,就可以获取多个元素或者,当我们懒得去找某一个元素的关键特征时,我们可以获取多个再遍历多个元素,去找到我们需要的那一个元素!同时,像登录页中,一般就两个input元素我们就可以直接获取,再根据代码找元素的顺序,是从根节点开始查找的所以,一般第一个输入框就是输入账号,第二个输入框就是输入密码input_elements=chromedriver.find_elements(By.TAG_NAME,'input')print(len(input_elements))#输入账号&密码input_elements[0].clear()input_elements[0].send_keys(username)time.sleep(1)input_elements[1].clear()input_elements[1].send_keys(password)获取多个元素,批量进行操作:#获取多个线段overhead_line=chromedriver.find_elements(By.XPATH,f"//span[@class='fancytree-title'and@title='架空线段']")time.sleep(3)#尝试点击多个线段forlineinoverhead_line:line.click()4.2、获取网页元素失败怎么办?1、确保4.1的方法都使用正确!!可能是获取到了多个确保使用正确的定位方式来定位元素。可以采用4.1中的方法2、检查我们的代码,获取的那个代码,是否有问题看清楚元素是div还是span,还是我之前就是因为这个,在那里找了半天的错误3、iframe的问题网页中的iframe(内联框架)是页面中嵌套的独立文档。在Selenium中,要与iframe中的元素进行交互,需要先切换到iframe上下文,然后才能执行操作。定位iframe元素iframe=driver.find_element_by_xpath("//iframe[@id='frame_id']")切换到iframe上下文driver.switch_to.frame(iframe)执行在iframe中的操作element_inside_iframe=driver.find_element_by_xpath("//button[@id='button_inside_iframe']")element_inside_iframe.click()切换回默认上下文driver.switch_to.default_content()如果iframe嵌套层级较深,你可能需要多次切换上下文来定位内部的iframe和元素。在处理复杂的页面结构时,建议先仔细分析页面结构,确保准确地切换到所需的iframe上下文。dialog_iframe=chromedriver.find_elements(By.TAG_NAME,"iframe")chromedriver.switch_to.frame(dialog_iframe[4])4、网页跳转的问题当我们进行了网页的一些操作时,会打开新的网页,这时候,我们还停留在原来的网页!我们需要切换到新的网页里面进行操作的话,也得进行切换!!!获取当前窗口句柄current_window_handle=driver.current_window_handle获取所有窗口句柄all_window_handles=driver.window_handles切换到新窗口句柄forwindow_handleinall_window_handles:ifwindow_handle!=current_window_handle:driver.switch_to.window(window_handle)break切换回原始窗口句柄(可选)driver.switch_to.window(current_window_handle)五、Selenium点击元素的方法当我们可以获取元素后,我们往往需要进行操作,其中无非就是输入+点击输入很简单,我们只需要3行代码input_element=chromedriver.find_element(By.ID,'findSource').find_element(By.TAG_NAME,'input')input_element.clear()input_element.send_keys('无人机')为了避免有错误,在输入前最好先清空一下里面的内容使用右键点击canvas_element=chromedriver.find_element(By.TAG_NAME,'canvas')ActionChains(chromedriver).context_click(canvas_element).perform()下面的都是左键的点击方法了方法描述click() 方法使用Selenium提供的 click() 方法直接触发元素的点击事件。JavaScript执行点击事件使用 driver.execute_script() 方法执行JavaScript代码,模拟触发点击事件。ActionChains类使用 ActionChains 类提供的方法模拟用户操作,包括点击操作。send_keys(Keys.RETURN) 方法对于某些元素,可以使用 send_keys(Keys.RETURN) 方法模拟按下回车键,从而触发点击事件。submit() 方法如果要点击的元素是一个表单中的提交按钮,可以直接使用 submit() 方法来提交表单,触发点击事件。使用JavaScript修改元素属性通过执行JavaScript代码来修改元素的属性,例如将元素的 onclick 属性设置为 null,然后再点击该元素。使用 pyautogui 或 Robot 类在某些情况下,可以使用 pyautogui 或 Robot 类来模拟鼠标点击,从而触发点击事件。在Selenium中触发点击事件(最常用的三种方法)1、使用click()方法:这是最简单和最常用的方法。通过选中要点击的元素,然后使用click()方法来触发点击事件。示例代码:element=driver.find_element_by_id("element_id")element.click()2、使用JavaScript执行点击事件:有时候使用Selenium的click()方法可能不够稳定,可以通过执行JavaScript代码来模拟点击事件。示例代码:element=driver.find_element_by_id("element_id")driver.execute_script("arguments[0].click();",element)3、使用ActionChains类:ActionChains类提供了模拟用户行为的方法,其中包括鼠标点击操作。示例代码:fromselenium.webdriver.common.action_chainsimportActionChainselement=driver.find_element_by_id("element_id")ActionChains(driver).click(element).perform()这些方法可以根据具体情况和需求选择合适的方式来触发点击事件。通常情况下,推荐优先使用click()方法,如果出现稳定性问题,可以尝试使用JavaScript执行点击事件或者ActionChains类来解决。另外四种(不常用)4、使用send_keys(Keys.RETURN)模拟回车键:对于某些元素,可以使用send_keys(Keys.RETURN)方法来模拟按下回车键,从而触发点击事件。示例代码:element=driver.find_element_by_id("element_id")element.send_keys(Keys.RETURN)5、使用submit()方法提交表单:如果要点击的元素是一个表单中的提交按钮,可以直接使用submit()方法来提交表单,触发点击事件。示例代码:form=driver.find_element_by_id("form_id")form.submit()6、使用JavaScript修改元素属性:可以通过执行JavaScript代码来修改元素的属性,从而触发点击事件。例如,将元素的onclick属性设置为null,然后再点击该元素。示例代码:element=driver.find_element_by_id("element_id")driver.execute_script("arguments[0].setAttribute('onclick','null');",element)element.click()7、使用Robot类模拟物理点击:在某些情况下,可以使用Python的pyautogui或Java的Robot类来模拟鼠标点击,从而触发点击事件。示例代码(Pythonpyautogui):importpyautoguielement=driver.find_element_by_id("element_id")element_location=element.locationpyautogui.click(element_location['x'],element_location['y'])这些方法可以根据具体情况和需求来选择合适的方式来实现点击事件。需要注意的是,每种方法都有其适用的场景和限制条件,选择时应根据具体情况进行权衡和判断。六、Selenium+browsermob-proxy获取网络请求为什么要获取网络请求,因为有一些数据是渲染到canvas里面的导致我们从网页中的元素里面拿取不到!那么就只有通过抓请求了!!!1.下载browsermob-proxy.batReleases·lightbody/browsermob-proxy·GitHubAfreeutilitytohelpwebdeveloperswatchandmanipulatenetworktrafficfromtheirAJAXapplications.-Releases·lightbody/browsermob-proxyhttps://links.jianshu.com/go?to=https%3A%2F%2Fgithub.com%2Flightbody%2Fbrowsermob-proxy%2Freleases要求jdk1.8以上下载JDK,可以直接使用Java8安装!java8安装教程:java8(jdk1.8u321)安装教程(超详细)_java8安装-CSDN博客 2.安装python模块browsermob-proxy pipinstall browsermob-proxy3、编写代码importtimefromseleniumimportwebdriverfrombrowsermobproxyimportServer#启动browsermob-proxy服务器server=Server(r"D:\browsermob-proxy-2.1.4\bin\browsermob-proxy.bat")server.start()proxy=server.create_proxy()#配置SeleniumWebDriver使用代理proxy_address="--proxy-server={0}".format(proxy.proxy)chrome_options=webdriver.ChromeOptions()chrome_options.add_argument(proxy_address)chrome_options.add_argument('--ignore-certificate-errors')driver=webdriver.Chrome(chrome_options=chrome_options)#开始记录网络请求proxy.new_har("page")#打开网页driver.get("https://baidu.com")time.sleep(3)#获取捕获的网络请求har=proxy.har#打印请求和响应内容forentryinhar['log']['entries']:request_url=entry['request']['url']response=entry['response']response_content=responseprint("RequestURL:",request_url)print("ResponseContent:",response_content)time.sleep(3)#关闭浏览器和proxy服务器driver.quit()server.stop()
|
|