前几天买了云服务器,这几天安装个python3环境,跑个selenium
1 一个结合文件发送,命令行,监控一体化的链接工具支持跨平台 http://www.hostbuf.com/?install_fs
按照顺序双击即可
2 命令行安装python(root身份),命令完全兼容centos7.6 https://www.linuxidc.com/Linux/2018-07/153286.htm
3 安装虚拟环境,此处有些小插曲,记录如下
安装虚拟机必要环境
可以先更新下pip
pip install --upgrade pip
sudo pip install virtualenv
sudo pip install virtualenvwrapper
安装结束就启动虚拟环境(如果不行可以重复操作)
source virtualenvwrapper.sh
创建虚拟环境(py3_flask是虚拟环境名字)
mkvirtualenv -p python3 py3_flask
查看虚拟环境(可用tab按钮,快捷方便)
workon py3_flask
退出虚拟环境
deactivate
删除虚拟环境(先退出才能删除)
rmvirtualenv py3_flask
查看虚拟环境新安装的包
pip freeze
4 这几天用本地软件跑selenium,网络不稳定,我都忘了我还有个云主机闲着。今天部署下
安装chrome
yum install https://dl.google.com/linux/direct/google-chrome-stable_current_x86_64.rpm
查看版本
在上面有 83.0.4103.116-1
下载chromedriver找对应版本 https://npm.taobao.org/mirrors/chromedriver/
wget http://npm.taobao.org/mirrors/chromedriver/83.0.4103.39/chromedriver_linux64.zip
chmod +x /home/mysoft/spyder/chromedriver
编辑py文件 此处给出一个可以正常运行的文件示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | #! /usr/bin/python3 from selenium import webdriver chrome_options = webdriver.ChromeOptions() # 不加载图片,加快访问速度 chrome_options.add_experimental_option( "prefs" , { "profile.mamaged_default_content_settings.images" : 2 }) # 此步骤很重要,设置为开发者模式,防止被各大网站识别出来使用了Selenium chrome_options.add_experimental_option( 'excludeSwitches' , [ 'enable-automation' ]) chrome_options.add_argument( '--headless' ) chrome_options.add_argument( '--no-sandbox' ) chrome_options.add_argument( '--disable-gpu' ) chrome_options.add_argument( '--disable-dev-shm-usage' ) browser = webdriver.Chrome(options = chrome_options) url = "https://www.baidu.com/" browser.get(url) html = browser.find_element_by_xpath( "//*" ).get_attribute( "outerHTML" ) print (html) print ( "-----------------------------------" )<br><br> |
记录几个报错
chrome not run,,,,,, 可能是chromeoption设置不好,参照以上代码
No such file or directory xxxx 可能是没有权限 chmod u+x xxxx
如果还有其他不可描述的错误。比如语法没错,但是就是通不过,可能是python缩进有问题,花费两三分钟统一下格式
查看正在运行的python程序 ps -ef | grep python
找到进程id 杀死进程 kill -9 4394
selenium的键盘按键的正确用法 https://www.jianshu.com/p/56e1295b031f
eg:driver.find_element_by_id('DomainName').send_keys("{ENTER}")
记录几个xpath的操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | driver.find_element_by_id( 'DomainName' ).clear() time.sleep( 0.2 * random.random()) driver.find_element_by_id( 'DomainName' ).send_keys( "%s.com\n" % (li)) driver.find_element_by_id( 'DomainName' ).send_keys( "{ENTER}" ) WebDriverWait(driver, 20 ).until(EC.presence_of_element_located((By.CLASS_NAME, 'search-write-btn' ))) # tag_element = driver.find_element_by_class_name('search-write-btn') # ActionChains(driver).move_to_element(tag_element).perform().click() time.sleep( 0.5 + 0.2 * random.random()) # driver.find_element_by_class_name('search-write-btn').click() # js ="document.getElementByClass('search-write-btn').click()" # js点击元素 # driver.execute_script(js) # 显示等待知道元素出现 WebDriverWait(driver, 20 ).until(EC.presence_of_element_located((By.CLASS_NAME, 'search-write-btn' ))) html = driver.find_element_by_xpath( "//*" ).get_attribute( "outerHTML" ) write_to_html( str (i),html) result = driver.find_element_by_xpath( "//*[contains(text(), '未被注册')]" ) |
记录几个刷新界面的方法 https://www.cnblogs.com/MasterMonkInTemple/p/4097512.html
在linux编程中,如果文件中用到当前目录,则应该cd 到指定目录下,不然程序会报路径找不到错误,另一种解决方式是在程序中获取当前路径,然后拼接
python中出现invalid syntax报错的几种原因
缩进不对,或者符号错误(某些无法描述的错误就是缩进不对)
目前还有一个奇葩错误
list' object has no attribute 'get'
问题是我用的是drivert.get(url) 并不是获取elements元素导致的错误,
解决方法:将except中异常处理的代码(driver.get(url))想办法放到try中。
某次点击按钮无法使用,解决办法:在输入框后面拼接字符串"\n" 不知为何,在win中运行很好,但是在linux下各种报错。
注意下try except用法,注意可能是哪个地方出错了,
注意只对绝对有异常的地方进行try 。。。。except pass。。。。。。。可以选择什么也不处理
(比如某元素找不到,程序会报异常进而终止运行,这时候必须try上,保证程序整体运行)
注意如果有需要,可多层嵌套try except 对于不同层侧的异常区别对待
注意 if a and b:pass else: 与 if a: if b:pass (a)else: 是不一样的
注意 如果比较某字符串相等,从字面看绝对没有不一样的,但是就是不相等,可能是utf8自动加载的字符bom等,处理方式编码方式修改为utf8-mas,或者,首行空一行
2020.07.13 18:00 继续记录bug
1 异常报错,网上说是文件开头没写# -*- coding: utf-8 -*-等编写方法导致错误,但是我修改了编码之后还是错,加上还是错,修改了编译环境还是错,修改了运行环境还是错
解决办法:可能是pycharm开的编译运行环境太杂乱导致,先关闭所有项目,然后关闭pycharm,然后关闭重启pycharm,,,,,,好了
2 driver获取元素必须先获取element,在获取信息,不方便,可以用lxml解析,具体步骤,lxml只识别文本,得先将driver转成str格式才能被解析
3 可以先用try xpath插件写语法,进行检测,推荐火狐浏览器安装try xpath,其他的我找不着
https://www.w3school.com.cn/xpath/xpath_syntax.asp
1 2 3 4 5 | from lxml import etree time.sleep( 0.1 + 0.5 * random.random()) html = driver.find_element_by_xpath( "//*" ).get_attribute( "outerHTML" ) html = etree.HTML(html) urls = html.xpath( "//*[@class='listBox2']/ul/li//h3/a/@href" ) texts = html.xpath( "//*[@class='listBox2']/ul/li//h3/a/text()" ) |
4 推荐个driver的写法,配置option使得可以无界面获取数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | def get_driver(): chrome_options = webdriver.ChromeOptions() # 不加载图片,加快访问速度 chrome_options.add_experimental_option( "prefs" , { "profile.mamaged_default_content_settings.images" : 2 }) # 此步骤很重要,设置为开发者模式,防止被各大网站识别出来使用了Selenium chrome_options.add_experimental_option( 'excludeSwitches' , [ 'enable-automation' ]) chrome_options.add_argument( '--headless' ) chrome_options.add_argument( '--no-sandbox' ) chrome_options.add_argument( '--disable-gpu' ) chrome_options.add_argument( '--disable-dev-shm-usage' ) #browser = webdriver.Chrome(executable_path="../chromedriver",options=chrome_options)#无界面的selenium browser = webdriver.Chrome(executable_path = "../chromedriver" ) #有界面的selenium return browser |
5 计算程序执行时间time.time()以秒为单位
6 复杂字符替换还是使用正则比较好 推荐菜鸟教程 https://blog.csdn.net/qq_20412595/article/details/82633501 group讲解比较详细
text = re.search(r"([0-9]*[-]?[0-9]*)(\S+)(大学排名|大学排行榜)", text_lis[i]).group(2)
url = re.search(r"../(\S+)", url_lis[i]).group(1)
7 找当前页面url driver.current_url 判断当前页和下一页是否在同一个页面判断跳转是否成功
8 xpath中contains可以配合属性和text()使用,,注意加点异常捕获
1 2 3 4 | try : driver.find_element_by_xpath( "//*[contains(@src, 'narNext.gif')]" ).click() except : pass |
9 数组连接可以用join
1 | f.write( "," .join(li)) |
10 正则表达式筛选中文,用group好点
1 2 | text = "全国服装设计专业" re.search(r "(全国|)(\S+)" ,text).group( 2 ) |
11 driver.get(url)即在原来的地址栏输入地址, driver.execute_script(url)即新开一个窗口输入地址 刷新页面driver.refresh() 获取当前页面url driver.current_url
12 driver切换窗口
1 2 3 4 | #切换窗口到最近打开的那一个(实际是切换句柄) driver.switch_to.window(driver.window_handles[ - 1 ]) # 等待窗口全部打开 webDriverWait(driver, 10 ).until(EC.new_window_is_opened(driver.window_handles))<br> # 创建一个新窗口driver.execute_script("https://baike.baidu.com/")<br><br><br> |
13 记得在每次界面有刷新之后延时一小会儿,我这边服务器慢,我延时3-3.6s左右,具体情况,具体分析
14 打开一个新的界面之后记得先切换窗口句柄,不然不可能获取到指定页面的元素
15 获取元素可能性很多,注意try except的嵌套使用
16 重新修改print方法实现log日志 https://www.jianshu.com/p/d485bb30c5bb (反正我一般不会用这种) (下面链接时我见过说log日志最简洁的一篇博客)
1 | https: / / mp.weixin.qq.com / s?src = 11 ×tamp = 1594766431 &ver = 2461 &signature = r5OfNsXrVLPm3ipxK0wbeoc2p4NPr7o9JQKoQgyRo8cuxcoMzYLX7zobIMpBg4q2hcrixANsnuhLcPl50smoCn0fKAbL0j7XiPVZusvDKY4D3OTImp41I50pUxFuX - vB&new = 1 |
1 | https: / / www.jb51.net / article / 165167.htm |
1 | https: / / www.cnblogs.com / itBlogToYpl / p / 12753067.html |
17 我参考别人的log日志封装了一个日志类
1 | https: / / blog.csdn.net / weixin_33991727 / article / details / 93362394 |
下面是我自己封装的log类,可以实现不同级别的log输出到不同的日志中
#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
该日志类可以把不同级别的日志输出到不同的日志文件中
'''
import os
import time
import logging
import inspect
handlers = {logging.NOTSET: "./tmp/TNLOG-notset.log",
logging.DEBUG: "./tmp/TNLOG-debug.log",
logging.INFO: "./tmp/TNLOG-info.log",
logging.WARNING: "./tmp/TNLOG-warning.log",
logging.ERROR: "./tmp/TNLOG-error.log",
logging.CRITICAL: "./tmp/TNLOG-critical.log"}
mylog = {
"info":"./tmp/TNLOG-mylog.log"
}
def createFile(filename):
path = filename[0:filename.rfind('/')]
if not os.path.isdir(path):
os.makedirs(path)
if not os.path.isfile(filename):
# 创建并打开一个新文件
fd = open(filename, mode='w', encoding='utf-8')
fd.close()
def createHandlers():
logLevels = handlers.keys()
for level in logLevels:
path = os.path.abspath(handlers[level])
createFile(handlers[level])
handlers[level] = logging.FileHandler(path)
myls = mylog.keys()
for myl in myls:
createFile(mylog[myl])
class TNLog(object):
def printfNow(self):
return time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
def __init__(self, level=logging.NOTSET):
# 加载模块时创建全局变量
self.__loggers = {}
logLevels = handlers.keys()
for level in logLevels:
logger = logging.getLogger(str(level))
# 如果不指定level,获得的handler似乎是同一个handler?
logger.addHandler(handlers[level])
logger.setLevel(level)
self.__loggers.update({level: logger})
def getLogMessage(self, level, message):
frame, filename, lineNo, functionName, code, unknowField = inspect.stack()[2]
'''日志格式:[时间] [类型] [记录代码] 信息'''
return "[%s] [%s] [%s - %s] %s" % (self.printfNow(), level, lineNo, functionName, message)
def info(self, message):
message = self.getLogMessage("info", message)
self.__loggers[logging.INFO].info(message)
def error(self, message):
message = self.getLogMessage("error", message)
self.__loggers[logging.ERROR].error(message)
def warning(self, message):
message = self.getLogMessage("warning", message)
self.__loggers[logging.WARNING].warning(message)
def debug(self, message):
message = self.getLogMessage("debug", message)
self.__loggers[logging.DEBUG].debug(message)
def critical(self, message):
message = self.getLogMessage("critical", message)
self.__loggers[logging.CRITICAL].critical(message)
def mymsg(self, message):
message = "[%s] %s\n" % (self.printfNow(), message)
path = mylog["info"]
with open(path, "a+", encoding='utf-8') as f:
f.write(message)
def logger():
createHandlers()
logger = TNLog()
return logger
if __name__ == "__main__":
logger = logger()
logger.debug("debug")
logger.info("info")
logger.warning("warning")
logger.error("error")
logger.critical("critical")
s = "检测结果 False 当前进度 5.597125720054636% 执行个数 1885 异常值个数 2726 当前检测 bgu "
logger.mymsg(s)
logger.mymsg(s)
logger.mymsg(s)
18 之前运行程序一直都是在前台,长循环程序总是莫名其妙退出,通过尝试,可以用shell脚本写个小脚本,省略那些麻烦的操作,执行某命令可以使得程序需后台运行,
这样就算本地断网也没关系啦。程序命名为xxx.sh
1 2 3 4 5 6 7 | #!/bin/bash # Your Answer # filename: cd.sh # chmod +x cd.sh # ./cd.sh /var/www cd / home / mysoft / spyder / choosecom / try32 / nohup python3 / home / mysoft / spyder / choosecom / try32 / try3.py > . / run.log 2 >& 1 & |
2020 07 18
19 今天继续爬虫,遇到一个问题,我xpath语法没错,在firefox上利用try xpath也可以获取,但是就是匹配不到,经过检查发现在模拟网页跳转之后,网页指针没有定位到当前页,导致页面元素获取不到。
因此在以后每次获取新页面并且要在新页面进行操作时,或者在当前页面关闭之后,可以加上
1 | driver.switch_to.window(driver.window_handles[ - 1 ]) |
1 2 | driver.close() driver.switch_to.window(driver.window_handles[ - 1 ]) |
20 经过摸索,我发现driver类似于单例模式,全局如果只是get一个出来,那全局都只会使用者一个driver,因此如果关闭当前页面一定要记得加上这么一句,反正不会错
1 | driver.switch_to.window(driver.window_handles[ - 1 ]) |
21 记录一个/引发的血案。今天爬取学校数据意外发现学校名称部分是错误的,这个错误刚开始没有发现,知道抓取学校信息时候,在控制台看到这个问题。也就是说,之前爬取的数据都是错误的,必须有重新抓。
解决办法,因为学校这一栏标签内部还有标签,我在爬取的时候没注意。可以使用xpath中//尝试抓取。竟然成功了。。。。与之前相比就是多了一个/
1 2 3 4 | # 之前的 school = " ".join(lis[0].xpath(" . / tr[ % s] / td[ 3 ] / text()" % i)) # 现在的 school = " ".join(lis[0].xpath(" . / tr[ % s] / td[ 3 ] / / text()" % i)) |
2020.07.20 记录几个写断点自动恢复的心得
22 注意每次用click之后要延时一会儿,可以用等待元素出现(隐式等待),或者直接暴力等待。
1 2 3 4 5 6 7 8 | from lxml import etree from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.common.action_chains import ActionChains webDriverWait(driver, 10 ).until(EC.new_window_is_opened(driver.window_handles)) |
23 我用的断点自动恢复的方法是将序号信息写入一个临时文件,命名为record,每次循环开始之前就从这个文件取序号数据(字符串格式)。循环用while来写,注意一般将循环加1操作放在循环最后,如果有特殊需要经过慎重考虑可以放在第一位,注意while的结束条件
24 如果是多重嵌套循环,一定注意,在内层循环结束之后,一定在外层将数据重新置零。不然错误不好找。(因为断点重传的变量在本方法内是全局变量)
25 不知道之前写没写,linux服务器后台运行程序
1 2 | cd / home / mysoft / spyder / major_sun / nohup python3 / home / mysoft / spyder / major_sun / sun_major_rank.py > . / run.log 2 >& 1 & |
2020/07/24 23:00
26 今天写爬虫,重温自己的下一页框架,在此小结一个
可以通过检测有点击下一页按钮,检测最新的driver与之前的driver的url是否相同,如果相同则说明已经到达最后一页,返回空,如果不一样,则返回driver。
因此,此方法的首页必须单独处理
27 元素获取文本信息是ele.text属性,而不是ele.text()方法。
28 对于跨区域的元素的点击事件,如果确定其可以正常工作,则可以加try except
29 关闭多于窗口,可以先在最开始设置变量before_handle为当前窗口,后续打开再多窗口,只要这个窗口不关闭,其他都可以关闭。可以构建死循环,一直关闭最后一个窗口,直到窗口等于before_handle 。然后从0开始关闭,,,,具体使用自己定
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构