服务器后台运行python程序-nohup命令

## 命令简介 nohup   nohup 命令   用途:LINUX命令用法,不挂断地运行命令。   语法:nohup Command [ Arg ... ] [ & ]   描述:nohup 命令运行由 Command 参数和任何相关的 Arg 参数指定的命令,忽略所有挂断(SIGHUP)信号。在注销后使用 nohup 命令运行后台中的程序。要运行后台中的 nohup 命令,添加 & ( 表示“and”的符号)到命令的尾部。   如果不将 nohup 命令的输出重定向,输出将附加到当前目录的 nohup.out 文件中。如果当前目录的 nohup.out 文件不可写,输出重定向到 $HOME/nohup.out 文件中。如果没有文件能创建或打开以用于追加,那么 Command 参数指定的命令不可调用。如果标准错误是一个终端,那么把指定的命令写给标准错误的所有输出作为标准输出重定向到相同的文件描述符。 ## 举例 ```python nohup python -u test.py > test.log 2>&1 & ``` 这条命令的意思是,执行test.py程序,并把程序中执行的情况记录到test.log文件中,包括程序异常、程序中打印的信息等。 PS: 也可以把上述命令写成nohup python -u test.py > nohup.out 2>&1 &唯一的区别就是把日志信息写到nohup.out文件中去了,两种做法都行。 输入后,回车。会打印出一个进程号。 可以通过jobs命令或者ps命令查看进程号 ![查看后台运行的进程号](https://img-blog.csdnimg.cn/20200209101546321.png) **==最后一步需要使用exit命令正常退出服务器==**,异常退出一样不能后台运行。 ![exit](https://img-blog.csdnimg.cn/20200209101826119.png) ## 应用场景 部署长期爬虫项目等

python selenium模拟浏览器操作实战(武汉大学原教务系统)

## 1.项目简介 因为信息门户如果用requests发post请求进行模拟登录的操作比较麻烦(自己太low,信息门户的加密算法没搞明白),所以没办法就只能考虑通过其他途径去做。 采用selenium就是一个比较好的解决办法(~~虽然比较慢,但是至少能用~~ ),模拟浏览器输入账号密码然后点击登录即可实现登录,然后获取相关cookies等信息就可以进行后续成绩获取等操作了。 ## 2.参考代码 ```python #!/usr/bin/env python # -*- coding:utf-8 -*- # Author : Gary import time from selenium import webdriver chrome_options = webdriver.ChromeOptions() # options.add_experimental_option('excludeSwitches', ['enable-automation'])#提示浏览器不是selenium chrome_options.add_argument('--headless') # 无头 chrome_options.add_argument('--disable-gpu') chrome_options.add_argument('--no-sandbox') # 这个配置很重要 chrome_options.add_experimental_option('excludeSwitches', ['enable-automation']) # 此步骤很重要,设置为开发者模式,防止被各大网站识别出来使用了Selenium class Selenium: def __init__(self): # self.driver = webdriver.Chrome(options=chrome_options) # 有配置的初始化浏览器 self.driver = webdriver.Chrome() # 不使用有配置的,方便看操作 self.driver.maximize_window() # 窗口最大化 def login(self, username, password): self.driver.get('http://ehall.whu.edu.cn/appShow?appId=5382714380693158') # 走信息门户认证的教务系统url,不用输入验证码 # 找到输入框并输入账号密码 Username = self.driver.find_element_by_id("username") Username.send_keys(username) Password = self.driver.find_element_by_id("password") Password.send_keys(password) time.sleep(0.2) self.driver.find_element_by_xpath('//*[@id="casLoginForm"]/p[5]/button').click() # 登录按钮 try: # name=self.driver.find_element_by_id("ampHeaderToolUserName").text#获取姓名,内容为空,弃用 name = self.driver.find_element_by_id("nameLable").text # 获取学生姓名 acade = self.driver.find_element_by_id("acade").text # 获取学生院系 # cookies = self.driver.get_cookies()[0] # print('登录成功 ...') # self.driver.quit() # html = self.driver.execute_script("return document.documentElement.outerHTML") html = self.driver.find_element_by_xpath('//*[@id="system"]').get_attribute('onclick') # 不要用 driver.page_source,那样得到的页面源码不标准 # print(html) csrftoken = html.split(",")[0].split('csrftoken=')[-1] print('登录成功!') return True, acade, name, self.driver.get_cookies(), csrftoken except Exception as e: print(str(e)) try: msg = self.driver.find_element_by_id("msg").text except Exception as e: # time.sleep(5) # cpatchaError=self.driver.find_element_by_id("cpatchaError").text print(str(e)) msg = '您尝试的次数过多,请明天再试!或解决方案:通过浏览器成功登录一次信息门户。再重试认证本系统' # self.driver.quit() return False, msg if __name__ == '__main__': username = 'test' # 你的信息门户账号 password = 'test' # 你的信息门户账号对应的密码 spider = Selenium() print(spider.login(username=username, password=password)) # 查看登录结果 ``` ## 3. todo或者应用 1. 登录成功后得到的cookies可以获取自己的成绩信息(计算GPA啥的)等 ~~2. 原本的抢课也是可以做的,但是换系统了用不了了~~

ubuntu 下MySQL 8.0 1055错误 永久解决方案

这是一次惨痛的教训,所以要记录一下,也和大家分享一下解决方案。 由于操作不当,把我自己的数据库给完全删除重装了。数据也没备份。哎 在解决这些需要改动配置的时候建议都先备份一下数据。 ==备份数据,备份数据,备份数据。== ## 问题描述 在MySQL数据库下,执行SQL插入语句报错或者进入数据库时。出现1055错误信息。 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20201123171948384.png#pic_center) ## 错误原因 在MySQL5.7之后,sql_mode中默认存在ONLY_FULL_GROUP_BY,SQL语句未通过ONLY_FULL_GROUP_BY语义检查所以报错。 ONLY_FULL_GROUP_BY:ONLY_FULL_GROUP_BY要求select语句中查询出来的列必须是明确的(其他语句也是一样)。   以SQL语句select columes from table group by list为例:columns必须是聚集函数或者在group by后的表达式list中,并且list中必须包含主键,否则也会报错。     insert、update、delete语句都会报错(但不影响SQL语句的执行),因为这三种语句执行之前也会执行查询操作。 以主键为id的表为例:   SELECT count(1) FROM customer GROUP BY name;该SQL执行成功,因为count是聚集函数;   SELECT * FROM customer GROUP BY name;该SQL执行失败,因为*中包含主键id,而group by后的表达式中并没有包含id   SELECT name FROM customer GROUP BY name;该SQL执行成功,因为name包含在group by后的表达式中   SELECT name, contact FROM customer GROUP BY name;该SQL执行失败,因为contact没有包含在group by后的表达式中 ## 解决方案 ### 一、永久解决 1)在MySQL下执行SELECT @@sql_mode语句    ![在这里插入图片描述](https://img-blog.csdnimg.cn/20201123171705627.png#pic_center) 2)将查询结果中的ONLY_FULL_GROUP_BY去掉然后复制,打开MySQL的配置文件,将sql_mode的值设置为复制的值(若没有sql_mode在[mysqld]下方添加一行即可)。 MySQL配置文件所在位置:安装版可通过windows服务所对应mysql启动项,查看其对应属性->可执行文件路径,获取my.ini路径。 免安装版一般在其根目录下。(默认是my-default.ini,必须将名字改为my.ini才能生效) #### ubuntu ```powershell vim /etc/mysql/mysql.conf.d/mysqld.cnf ``` 安装位置不同的,找到这个mysqld.cnf这个文件然后修改即可 若没有sql_mode在[mysqld]下方添加一行即可 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20201123171724807.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDM4ODA5Mg==,size_16,color_FFFFFF,t_70#pic_center)  sql_mode=…(删掉ONLY_FULL_GROUP_BY的那段)  3)重新MySQL服务即可生效! ### 临时方案 连接上mysql后,删除ONLY_FULL_GROUP_BY模式即可: `SET sql_mode=(SELECT REPLACE(@@sql_mode, 'ONLY_FULL_GROUP_BY', ''));`

MySQL数据在C盘如何转移到其它盘

## 前言 Windows环境下,肯定有很多小伙伴和我一样当初安装MySQL的时候没有更改盘符,导致现在C盘越来越大,那我们如何将数据全部转移到其它盘,并将数据的保存路径设置到其它盘? linux操作类似就不重复说明了 ## 操作过程 以下操作都默认连接上了数据库,windows可以通过Navicat等可视化工具,也可以用命令行进行操作。 首先通过命令查询一下数据存在哪里 ```bash show global variables like "%datadir%"; ``` ![在这里插入图片描述](https://img-blog.csdnimg.cn/20201201162707144.png) Linux用cd,vim、mkdir、mv等命令进行以下操作。 进入文件管理器输入这个路径直接打开它,就可以看到你的所有库都在这里。 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20201201163019779.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDM4ODA5Mg==,size_16,color_FFFFFF,t_70) 找到MySQL的配置文件my.ini,这个配置文件一般跟data文件夹在一起,data往上一级应该就可以找到,默认在C:\ProgramData\MySQL\MySQL Server 8.0(后面的是版本号) 打开配置文件搜索:datadir ![在这里插入图片描述](https://img-blog.csdnimg.cn/2020120116340712.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDM4ODA5Mg==,size_16,color_FFFFFF,t_70) 在前面加一个#将其注释掉,然后自己设置一个存储路径,我在E盘新建了一个mysql作为新的存储路径,保存这个文件 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20201201163443982.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDM4ODA5Mg==,size_16,color_FFFFFF,t_70) 将原本C:\ProgramData\MySQL\MySQL Server 8.0\Data\中的全部数转移到新的路径中,并重启MySQL服务即可,建议直接重启一下电脑。 ==大功告成。==

python采用requests+bs4爬取Gary个人博客学习页面并用mysql存储(https://www.gary666.com/learn)

## 爬取说明 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200717115106980.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDM4ODA5Mg==,size_16,color_FFFFFF,t_70) 博客链接:[链接](https://www.gary666.com/learn),https://www.gary666.com/learn 输出:页面中所有的文章的标题、内容、作者、文章分类、时间 对应上图(作者是Gary、文章分类python、时间20220-7-9) ## 参考代码 ```python # -*- coding: utf-8 -*- # author:Gary # 第一步,导入需要用到的库 import requests from bs4 import BeautifulSoup # 根据需要引入存储数据的库 import pymysql import time # 设置爬取时间间隔,防止访问过快ip被封等 # 第二步,请求网页内容 url = 'https://gary666.com/learn' # 需要请求的网页的链接 html = requests.get(url) # get方式请求数据 # print(html.status_code) # 查看请求的状态码(200表示请求正常,404内容没有找到) html.encoding = html.apparent_encoding # 设置编码,防止由于编码问题导致文字错乱 # print(html.text) # 查看请求到的内容 html_content = html.text # 第三步,解析你需要的内容 # html.parser,lxml soup = BeautifulSoup(html_content, "html.parser") all_div = soup.find_all("div", class_="blogs") # 观察发现所有的内容都在class为blogs的div中,所以直接定位 # print(all_div) data_list = [] # 存储所有数据,供存储使用 for div in all_div: # 循环查看每个超链接的文字和url if div is None: # 如果div的内容为空 continue else: title = div.find('h3').find('a').text # 文章标题 content = div.find('p').text # 文章内容 author = div.find('li', class_='author').text # 作者 t_type = div.find('li', class_='lmname').text # 文章分类 timer = div.find('li', class_='timer').text # 时间 single_blog = (title, content, author, t_type, timer) # 单个blog内容 data_list.append(single_blog) # 添加到所有的数据中去 print(title, content, author, t_type, timer) # 选做内容 # 第四步,存储数据 def insert_data(datalist): # 连接数据库,主机名默认本地,端口默认3306,用户名默认root,字符集默认utf-8,需要传入数据库密码和数据库名 # 你的密码password参数,数据库名db参数,下面示例密码是your_password,数据库名是spider(需要自己先建立好数据库表) conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', password='your_password', db='spider', charset='utf8') # 连接数据库 cur = conn.cursor() # 用于访问和操作数据库中的数据(一个游标,像一个指针) # 示例是spider中建立了blog表,然后表的属性有title, content, author, t_type, timer,正常运行先需要建立好 # content的数据类型建议设为text sql = 'insert into blog(title, content, author, t_type, timer) values(%s,%s,%s,%s,%s)' # 插入多条 cur.executemany(sql, datalist) # data_list类型是列表中嵌套多个元组比如[(),(),()] conn.commit() # 提交事务,执行了这一步数据才真正存到数据库 ''' 如果需要单条插入放入到上面循环的36行后执行即可 sql='insert into blog(title, content, author, t_type, timer) values("{}","{}","{}", "{}","{}")'.format(title, content, author, t_type, timer)#插入单条 cur.execute(sql) ''' cur.close() # 关闭游标 conn.close() # 关闭数据库连接 # 执行插入数据函数 # print(data_list) # insert_data(data_list) # 爬取多页(爬取其他页面数据) def many_page(page): # 设置头部信息 headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36'} # url = 'https://gary666.com/learn?page=2' # 通过观察发现是否page控制的翻页,page=几就是第几页 # 方法一,直接修改url(参数不多推荐这个) single_url = 'https://gary666.com/learn?page={}'.format(page) res = requests.get(single_url, headers=headers) # 获取网页内容 # 方法二,构造参数,通过参数 ''' params = {'page':page} res=requests.get(url='https://gary666.com/learn',params=params,headers=headers)#获取网页内容 ''' res.encoding = res.apparent_encoding # 设置编码 if res.status_code == 200: # 如果状态码为200则正常 return res.text # 返回网页内容 else: print('爬取网页异常') # 通过bs4解析网页内容 def ana_html(html): soup = BeautifulSoup(html, "html.parser") all_div = soup.find_all("div", class_="blogs") # 观察发现所有的内容都在class为blogs的div中,所以直接定位 # print(all_div) data_list = [] # 存储所有数据,供存储使用 for div in all_div: # 循环查看每个超链接的文字和url if div is None: # 如果div的内容为空 continue else: title = div.find('h3').find('a').text # 文章标题 content = div.find('p').text # 文章内容 author = div.find('li', class_='author').text # 作者 t_type = div.find('li', class_='lmname').text # 文章分类 timer = div.find('li', class_='timer').text # 时间 single_blog = (title, content, author, t_type, timer) # 单个blog内容 data_list.append(single_blog) # 添加到所有的数据中去 print(title, content, author, t_type, timer) return data_list # 返回数据列表 if __name__ == '__main__': for page in range(1, 9): # range的范围就是页数的范围 print('正在爬取第{}页'.format(page)) html = many_page(page) # 获取网页内容 data_list = ana_html(html) # 解析需要的内容 time.sleep(0.5) # 每爬取一次停止0.5s在继续爬取 insert_data(data_list) # 存储数据 print('爬取完成!') ```

Top