• 最新文章
  • 学习笔记
  • 生活杂谈

搬运:python构建一个Selenium脚本

搬运:python构建一个Selenium脚本 搬运selenium手册的一篇,作笔记备忘。 逐步构建一个Selenium脚本的说明 当你完成 Selenium安装 后, 便可以开始书写Selenium脚本了. 八个基本组成部分 Selenium所做的一切, 就是发送给浏览器命令, 用以执行某些操作或为信息发送请求. 您将使用Selenium执行的大部分操作, 都是以下基本命令的组合 点击 “View full example on GitHub” 的链接以查看上下文中的代码. 1. 使用驱动实例开启会话 关于如何启动会话,请浏览我们的文档 驱动会话 1driver = webdriver.Chrome() 2. 在浏览器上执行操作 在本例中, 我们 导航 到一个网页. xxxxxxxxxx 1 1 driver.get(\"https://www.selenium.dev/selenium/web/web-form.html\") 3. 请求 浏览器信息 您可以请求一系列关于浏览器的信息 , 包括窗口句柄、浏览器尺寸/位置、cookie、警报等. xxxxxxxxxx 1 1 title = driver.title 4. 建立等待策略 将代码与浏览器的当前状态同步 是Selenium面临的最大挑战之一, 做好它是一个高级主题. 基本上, 您希望在尝试定位元素之前, 确保该元素位于页面上, 并且在尝试与该元素交互之前, 该元素处于可交互状态. 隐式等待很少是最好的解决方案, 但在这里最容易演示, 所以我们将使用它作为占位符. 阅读更多关于等待策略 的信息. xxxxxxxxxx 1 1 driver.implicitly_wait(0.5) 5. 发送命令 查找元素 大多数Selenium会话中的主要命令都与元素相关, 如果不先找到元素, 就无法与之交互. xxxxxxxxxx 2 1 text_box = driver.find_element(by=By.NAME, value=\"my-text\") 2 submit_button = driver.find_element(by=By.CSS_SELECTOR, value=\"button\") 6. 操作元素 对于一个元素, 只有少数几个操作可以执行, 但您将经常使用它们. xxxxxxxxxx 2 1 text_box.send_keys(\"Selenium\") 2 submit_button.click() 7. 获取元素信息 元素存储了很多被请求的信息. xxxxxxxxxx 2 1 message = driver.find_element(by=By.ID, value=\"message\") 2 text = message.text 8. 结束会话 这将结束驱动程序进程, 默认情况下, 该进程也会关闭浏览器. 无法向此驱动程序实例发送更多命令. 详见 Quitting Sessions. xxxxxxxxxx 1 1 driver.quit()   搬运来源:https://www.selenium.dev/zh-cn/documentation/webdriver/getting_started/first_script/
搬运:python构建一个Selenium脚本

算法基础:动态规划(二)

算法基础:动态规划(二)   算法基础:动态规划(二) 关于动态规划,这里再举一个书上的经典例子。 求最长公共子序列(LCS) 问题描述: 令序列X=x1x2x3...xm ,序列 Y=y1y2...yk 是X 的子序列,存在X 的一个严格递增下标序列<i1,i2,...,ik>,使得对于所有的j=1,2,...,k有xij=yj。例如,X=ABCBDAB,Y=BCDB,则Y是X的一个子序列。 给定两个序列X和Y,称序列Z是和X和Y的公共子序列,是指Z同时是X和Y的组序列。最长公共子序列问题定义为:给定序列X=x1x2...xm和Y=y1y2...yn,求这两个序列的最长公共子序列 。以X=ABCBDAB,Y=BCDB为例,两者的公共子序列为Z=BCDB。 问题分析: 如果是匹配字符串问题的话,可以用经典KMP算法,可惜不是,求不得。如果使用暴力算法,穷举X的所有子序列,并与Y序列比较,其时间复杂度可以达到O(2mn),对于长序列来说,这个代价是不可接受的。那我们使用动态规划按照以下步骤来解决这个问题: 1)刻画最长公共子序列问题的最优子结构。 设X=x1x2...xm和Y=y1y2...yn是两个序列,Z=z1z2...zk是X和Y的一个最长公共子序列。 (1)如果xm=yn,那么zk=xm=yn,且Zk−1是Xm−1和Yn−1的一个最长公共子序列。 (2)如果xm≠yn,那么zk≠xm,蕴含着Z是Xm−1和Y的一个最长公共子序列。 (3)如果xm≠yn,那么zk≠yn,蕴含着Z是X和Yn−1的一个最长公共子序列。 2) 递归定义最优解的值 或且且l={0,i=0或j=0l,i,j>0且xi=yjmax(l,l),i,j>0且xi≠yj 3) 代码演示 C++ ​x941#include <algorithm> 2 #include <iostream> 3 #include <vector> 4 5 using std::cout; 6 using std::endl; 7 using std::string; 8 using std::vector; 9 10 11 12 //算法主体 13 void Match(string x,string y,int lenx,int leny){ 14 15    //建立图表 16    vector<vector<std::pair<int,int>>> diagram(lenx+1); 17    for(auto & v:diagram){ 18        v.resize(leny+1,{0,0}); // 初始化 19   } 20     21 22    // pair的第二位用于表示当前字符是否属于X和Y的公共子序列 23    // 1,2分别表示“当前X的字符不在公共子序列中,且当前X_i与Y_j的LCS和X_(i-1)与Y_j的LCS一样\", 24    // ”当前Y的字符不在公共子序列中,且当前X_i与Y_j的LCS和X_i与Y_(j-1)的LCS一样\" 25    // 3表示当前X与Y字符相等,且X_i与Y_j的LCS等于X_(i-1)与Y_(j-1)的LCS+1 26    for(int i = 1; i < lenx+1 ; ++i){ 27        for(int j = 1; j < leny+1 ; ++j){ 28            if(x == y){ 29                diagram.first = diagram.first+1; 30                diagram.second = 3; 31           } 32            else{ 33                if(diagram.first > diagram.first){ 34                    diagram.first = diagram.first; 35      
算法基础:动态规划(二)

基础算法:动态规划(一)

基础算法:动态规划(一) 基础算法:动态规划(一) 前言: 以前光憋算法题,但一直没弄清楚动态规划的使用方法。后来找了算法分析的黑书,但内容非常多,导致一直没时间看。最近在学习软件设计,教材里面对动态规划、贪心算法、回溯法这几种常见的基础算法进行了相当简洁的讲解,使我理解了许多,故此下笔。 这篇文章分为算法目标、适用条件、步骤设计、代码示例四个部分。 算法目标: 一般来说,是为了解决问题在有约束条件下的全局最优解。一个问题如果具有以下两个性质,就可以考虑使用动态规划法求解。 (1)最优子结构。即一个问题的最优解中包含了其子问题的最优解,或者说是由子问题的最优解构成。需要注意到的是,问题适用动态规划算法时也可能使用于贪心算法。 (2)重叠子问题。重叠子问题指的是用来解决原问题的递归算法可反复地解同样的子问题,而并不总是在产生新的子问题。相比于没有记忆的分治法在每次遇到相同子问题时都会视作一个新问题重新计算而言,动态规划自底向上计算,解决一个问题需要的子问题结果被保存在记录表中,随时可供使用,效率大大提高。 步骤设计: 使用动态规划解决这类问题,通常按照以下几个步骤进行: (1)找出最优解的性质,并刻画其结构特征。 (2)递归地定义最优解的值。 (3)以自底向上的方式计算出最优值 (4)根据计算最优值时得到的信息,构造一个最优解。 例如经典的0-1背包问题,即是在背包容量有限的情况下,尽量往背包里装最高价值的物品。背包容量是约束条件,争取总价值最高是寻找问题的最优解。其中0-1指的物品只能有被整个装入或者不装两种状态,拿取物品的方案则可以看作一系列0和1的组合。以一个具体的例子来说明: 物品(i) 1 2 3 4 5 6 7 重量(wi) 4 5 10 11 13 14 17 价值(vi) 3 4 7 8 9 10 11 设背包初始容量W=30,则该问题可以形式化描述如下: 目标函数为max(∑i=1nvixi) 约束条件为∑i=1nwixi≤W 该问题的求解过程可以看作是进行一系列的决策过程。假设背包容量为W,vi和wi分别表示第i个物品的价值和重量,xi=1表示装入第i个物品。如果一个方案里的最优解包含了“装入物品n”,即xn=1,则在选择物品1、2、...、n-1时,一定有容量为W-wn的最优解。反之,最优解没有包含“装入物品n”,即xn=0,则在选择物品1、2、...、n-1时,一定有容量为W的最优解。显然地,对每个物品的选择都适用于这个模式,都是全局问题的子问题。 根据上面的分析的最优解的结构可以递归的定义问题的最优解。设c表示背包容量为w时选择物品i所导致的最优解的总价值,得到下式。 能看到,在物品i可以被装入背包时,我们通过比较装入和不装入后的总价值来确定是否该装入。 编写C代码 ​x1#include <iostream> 2 3 using std::endl; 4 using std::cout; 5 6 int * selects = nullptr; 7 int ** diagram = nullptr; // 存储各选择下的最优解 8 9 // 打印选择 10 void printSelects(int * content,int n){ 11    cout << \"selects:; 14        if(i < n-1){ 15            cout << \",\"; 16       } 17   } 18    cout << \"]\" << endl; 19 } 20 21 // 打印表格 22 void getDiagram(int W,int n){ 23    for (int i = 1 ; i <= n ; ++i){ 24        for (int j = 1 ; j <= W ; ++j){ 25            printf(\"%-4d\",diagram); 26       } 27        printf(\"\\n\"); 28   } 29 } 30 31 // 释放图的空间 32
基础算法:动态规划(一)

为minecraft安装complementary shaders材质包(安装fbric)

总所周知,mc的社区生态是十分优秀的,但之前我从来没有想过为我的mc安装一些插件,一是觉得原版mc的内容其实已经足够丰富,二是我一直没有给游戏装mod的习惯。今天想要给我的养老档安装一个便宜材质包,想看看是什么样滴感觉~ 目标瞄准的的是complementary shaders,以更新频,性能要求低,质量能打著称。有着Unbound和Reimagined两种类型。
为minecraft安装complementary shaders材质包(安装fbric)

linux的文件权限问题

文件权限 最近尝试配置wordpress环境,想在上面记录一些自己的笔记。 配置环境过程中遇到了很多文件权限的问题,故写下第一篇,也是测试一下wordpress好不好用。 实验是这样的,假设一般使用的账户为User_A,另一个为User_B。 User_A设置家目录一个文件夹,随后建立一个以User_B为拥有者的文件,文件夹设置其他用户不可访问的权限,A和B是不同组,想测试User_B能不能直接访问本属于User_A用户的文件夹下的自己的文件。 // 不让其他用户可用 mkdir 700 ~/testdir cd ./testdir vim test.txt // 把文件交给User_B chown User_B:User_B test.txt su User_B // 直接访问 vim /home/User_A/testdir/test.txt 不出意外,没权限访问,即使打开vim,底下也显示“Permission Denied”。 修改权限再试试。 su User_A // 给予B用户可读权限 chmod 704 ~/testdir su User_B // 直接访问 vim /home/User_A/testdir/test.txt 这次情况倒是出乎我意料,权限依旧被拒绝。按道理,如果可以读取文件夹,那么文件夹下的自己的文件应该可以被User_B访问啊。 原因就是:我混淆了执行和可读两种权限的作用。 可读权限是允许用户查看目录内容,如果这时使用 xxxxxxxxxx cat /home/User_A/testdir 那么就会打印testdir目录下的所有文件名。 因为文件夹(目录)本身只存放文件夹下所有文件的索引(存放位置),甚至这些索引通常也不指向文件的真实位置,而是指向的文件控制块(FCB)或者inode之类的。所以并非文件夹去存放其下文件本身,而文件夹只是一个索引块,这也是sc小学二年级就学过的知识。 可以想到的是,调用文件夹,就可以去访问其下文件。于是有 xxxxxxxxxx su User_A // 给予B用户可执行权限 chmod 701 ~/testdir su User_B // 直接访问 vim /home/User_A/testdir/test.txt 可以访问,并做出修改。 注意到这时候没有给予B可读文件夹的权限,于是 // 正常cd,说明cd正是调用了文件夹,而不是“读取”了文件夹 cd /home/User_A/testdir // 权限被拒绝,说明ls只是打印了其下文件名 ls 另外,在只有只读权限,没有执行权限的情况下。User_B用户 ls 该文件夹,会出现只能打印文件名,而无法显示其相关信息的情况。这正说明,系统是通过调用文件夹的索引去寻找其下文件的控制块。      
linux的文件权限问题