一、selenium获取网站数据
背景介绍
这篇文章主要包含以下几个内容
- 使用
selenium
进行网站登录签到并获取积分数据 - 基于
QQ邮箱
发送邮件 - 在
linux
安装google-chrome
和selenium
,并上传代码到linux(centos 8) - 使用
crontab
实现定时执行爬虫
环境说明
selenium 4.1.3
python3.8.5
CentOS 8
默认已安装python解释器,selenium的使用方法和对应的浏览器驱动看我的另一篇文章:selenium知识大全-传送门
- 查看Chrome版本
设置 – 关于Chrome 即可查看你的浏览器版本 - 下载对应的浏览器驱动
Chrome驱动下载地址:http://chromedriver.storage.googleapis.com/index.html
火狐驱动下载地址:http://ftp.mozilla.org/pub/firefox/releases/
1. 准备环境
- 安装selenium
pip install selenium
2. 分析网站
- 网站登录是一个
input
标签,通过ID
可以确定对应的输入框来输入用户名和密码
账号id='account' ,密码id='password'
# 两种定位方式都可以,self.account表示你的账号,self.password表示你的密码
# account = WebDriverWait(driver,10).until(EC.presence_of_element_located((By.ID,"account"))).send_keys(self.account)
account = driver.find_element(By.ID,"account").send_keys(self.account)
# 点击账号
# password = WebDriverWait(driver,10).until(EC.presence_of_element_located((By.ID,"password"))).send_keys(self.password)
password = driver.find_element(By.ID, "password").send_keys(self.password)
# 点击密码
- 再定位登录按钮,你会发现按钮的class属性,每次刷新页面,有的值不一样,有的值一样。
- 我们可以通过标签的文字内容来定位标签,页面只有一个按钮的文字为登录,所以我们可以这样写
WebDriverWait(driver,10).until(EC.presence_of_element_located((By.XPATH,'//button[text()="登录"]'))).click()
- 注册的时候会出现要求同意的按钮,但是我们再次登录时不会出现。我们把代码进行整理一下
import datetime
from selenium import webdriver
import time
import random
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
driver = webdriver.Chrome(self.chromedriver)
driver.get('url')
time.sleep(random.uniform(1,2)) # 防止网页出现渲染意外
account = WebDriverWait(driver,10).until(EC.presence_of_element_located((By.ID,"account"))).send_keys(self.account)
# 点击账号
password = WebDriverWait(driver,10).until(EC.presence_of_element_located((By.ID,"password"))).send_keys(self.password)
# 点击密码
login = WebDriverWait(driver,10).until(EC.presence_of_element_located((By.XPATH,'//button[text()="登录"]'))).click()
# 点击登录 ,开始登录
5.登录成功后,我们直接打开个人中心,通过xpath语法直接定位标签
3. 网页代码整理
我们的数据已经获取,这是网页的所需的所有代码,做了异常处理
import datetime
from selenium import webdriver
import time
import random
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
class KuJiaLe(object):
"""
酷家乐签到并获取一些数据
"""
def __init__(self):
self.url = 'https://www.kujiale.cn/signin?'
self.chromedriver = './chromedriver.exe' # 注意驱动与浏览器版本对应。
self.account = '666666666' # 网站的账号
self.password = '666666' # 网站的密码
self.isSuccess = None # 是否爬取成功
self.integral = None # 积分
self.flag = None # 0 表示失败,1表示成功
self.start_time = time.time() # 统计爬取时间
self.failedCount = 0 # 统计失败次数
self.failedList = [] # 失败信息加入列表中
def get_result(self):
try:
driver = webdriver.Chrome(self.chromedriver)
driver.get(self.url)
time.sleep(random.uniform(1,2))
print('开始爬取某*乐 {}'.format(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S %A')))
account = WebDriverWait(driver,10).until(EC.presence_of_element_located((By.ID,"account"))).send_keys(self.account)
# 点击账号
password = WebDriverWait(driver,10).until(EC.presence_of_element_located((By.ID,"password"))).send_keys(self.password)
# 点击密码
login = WebDriverWait(driver,10).until(EC.presence_of_element_located((By.XPATH,'//button[text()="登录"]'))).click()
# 点击登录 ,开始登录
time.sleep(random.uniform(1,2))
driver.get('https://www.kujiale.cn/activities/jifengonglue')
# 跳转到签到页面
WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, "//*[@class='single-image']/div[3]"))).click()
# 点击签到
time.sleep(random.uniform(1,2))
driver.get('https://www.kujiale.cn/pcenter')
# 跳转到个人主页
integral = WebDriverWait(driver,10).until(EC.presence_of_element_located((By.XPATH,'//*[@id="up-site-dash-board"]/div[1]/div/div[2]/div[1]/a/div/span'))).text
# 获取用户积分
self.flag = 1
self.isSuccess = '签到成功'
self.integral = integral
print('爬取成功..............')
except Exception as e:
print(e)
self.flag = 0
self.isSuccess = '签到失败'
self.failedList.append("签到失败,时间:" + datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S %A'))
self.failedCount += 1
if self.failedCount == 5:
self.flag = 1
return self.flag
print('爬取失败..............')
return self.flag
def start(self):
flag = self.get_result()
# print(flag)
if flag == 0: # 0 表示失败了
print('爬取失败 {} 次'.format(self.failedCount))
while True:
time.sleep(60) # 过60秒再次尝试登录
ret = self.get_result()
if ret == 1: # 5次后默认跳出
break
data = {
"now_time": datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S %A'),
"website": "某*乐 ",
"isSuccess": self.isSuccess,
"integral": str(self.integral),
"useTime":round(time.time() - self.start_time,2),
"failedInfo":{
"failedCount": self.failedCount,
"failedList":self.failedList
}
}
print('数据整理完成...........')
return data
if __name__ == '__main__':
kjl = KuJiaLe()
data = kjl.start()
print(data)
运行结果如下:
二、QQ邮箱发送邮件
1. 开启QQ邮箱 POP/SMTP
- 登录QQ网页邮箱,点击 设置 – 账户
找到POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务
,开启POP/SMTP
服务,点击生存授权码
2. 使用smtp实现发送QQ邮件
import smtplib
from email.mime.text import MIMEText
from email.header import Header
class QQEmail():
def __init__(self):
self.email_host = "smtp.qq.com" # 设置的邮件服务器host必须是发送邮箱的服务器,与接收邮箱无关。
self.sender_email = "123456@qq.com" # 发送方qq邮箱
self.receiver_email = "123456@qq.com" # 接收方qq邮箱
self.email_authorization = "ag*********ac" # 开启stmp服务的时候并返回的授权码,是接收方QQ的授权码。
def send_email(self,email_theme,email_content):
"""
发送邮件函数
email_theme: 接收一个字符串,用于设置邮件的主题
email_content: 接收一个字符串,用于设置邮件的内容
"""
print('开始发送邮件至: {}'.format(self.sender_email))
message = MIMEText(email_content, 'plain', 'utf-8') # 邮件内容,三个参数:第一个为文本内容,第二个设置文本格式 plain表示字符内容, ,第三个设置编码 utf-8
message['Subject'] = email_theme # 设置邮件的主题,即邮件标题
message['From'] = Header("ZanSan", 'utf-8') # 设置显示在邮件里的发件人名称
message['To'] = Header("LiSi", 'utf-8') # 设置显示在邮件里的收件人名称
try:
smtpobj = smtplib.SMTP_SSL(self.email_host, 465) # 本地如果有本地服务器,则用localhost ,默认端口25,腾讯的(端口465或587)
smtpobj.set_debuglevel(1) # 设置调试输出级别。 如果 level 的值为 1 或 True ,就会产生连接的调试信息,以及所有发送和接收服务器的信息。 如果 level 的值为 2 ,则这些信息会被加上时间戳。
smtpobj.login(self.receiver_email, self.email_authorization) # 登陆QQ邮箱服务器
smtpobj.sendmail(self.sender_email, [self.receiver_email], message.as_string()) # 发送邮件。这里要注意一下第三个参数,msg是字符串,表示邮件。我们知道邮件一般由标题,发信人,收件人,邮件内容,
print("邮件发送成功")
smtpobj.quit() # 退出
except smtplib.SMTPException as e:
print("邮件发送失败,Error: {}".format(e))
if __name__ == '__main__':
email_theme = 'QQ邮件发送--我是主题'
email_content = '我是内容,我是内容,我是内容'
q = QQEmail()
q.send_email(email_theme,email_content)
运行效果如下:
注意:现在QQ在进行发送和接收时,发送方和接收方的QQ必须相同了,不相同会报错
三、Linux 安装谷歌浏览器及驱动并测试
3.1 使用阿里源
因为现在centos8 不再进行维护了,阿里更换的centos8的repo源地址。
1. 备份
mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
2. 更换新的阿里源
wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-vault-8.5.2111.repo
3. 删除缓存,重新生成新缓存
yum clean all
yum makecache
如果出现 Couldn’t resolve host ‘mirrors.cloud.aliyuncs.com’ 信息,不影响使用。用户也可自行修改相关配置: eg:
sed -i -e '/mirrors.cloud.aliyuncs.com/d' -e '/mirrors.aliyuncs.com/d' /etc/yum.repos.d/CentOS-Base.repo
3.2 安装谷歌浏览器
1. yum 安装谷歌浏览器
yum install https://dl.google.com/linux/direct/google-chrome-stable_current_x86_64.rpm
注意:
如果出现如下error
,把/etc/yum.repos.d/*
所有的文件移动到其他地方,然后重新执行更换阿里云源【3.1 小节 - 第二小点】
2. 查看谷歌浏览器版本
google-chrome-stable --version
3.3 下载谷歌浏览器驱动
谷歌浏览器驱动下载网址:http://chromedriver.storage.googleapis.com/index.html
1. 找到与谷歌浏览器对应的驱动版本,右键复制链接
2. 下载驱动
wget http://chromedriver.storage.googleapis.com/99.0.4844.51/chromedriver_linux64.zip
3. 解压文件
unzip chromedriver_linux64.zip
# 如果没有unzip命令,直接安装即可
# yum install unzip
4. 把驱动文件移动到/usr/bin/ 目录下
mv chromedriver /usr/bin/
3.4 创建爬虫专业虚拟环境 (Linux环境)
为了更好的隔离本地环境与虚拟环境,使程序运行更稳定,推荐每个项目之间使用虚拟环境相互隔离。
1. 安装 virutalenvwrapper 虚拟环境工具
#
pip3 install virtualenvwrapper
2. 配置.bashrc 文件
# 1.打开文件
vim ~/.bashrc
# 2.添加内容
VIRTUALENVWRAPPER_PYTHON=/usr/local/bin/python3.8 # 设置python解释器环境路径
export WORKON_HOME=/home/pythonCode/virtualSet/ # 创建的虚拟环境所在那个目录下
source /usr/local/bin/virtualenvwrapper.sh # 执行文件
退出vim后,执行 source ~/.bashrc
。
3. virutalenvwrapper 介绍
操作 | 命令 |
---|---|
切换到摸个虚拟环境 | workon [virutalenv name] |
退出虚拟环境 | deactivate |
列出所有虚拟环境 | lsvirtualenv = workon |
删除某个虚拟环境 | rmvirtualenv [virutalenv name] |
指定python解释器 | mkvirtualenv -p python3.8 test |
创建虚拟环境 | mkvirtualenv env_name |
4. 创建selenium虚拟环境
mkvirtualenv seleniumEnv
在创建成功后,该工具会默认进入虚拟环境中
我们也可以使用 workon
指令来进入不同的环境
5. 安装selenium
一定是在虚拟环境下安装哦
(seleniumEnv) [root@centos8-106 home]# pip install selenium
3.5 整合代码并复制到Linux
我们需要整合爬虫代码和发送QQ邮件的代码,来实现爬取信息发送邮件的效果。
QQ邮箱的代码不需要改动,只需要改动一下爬虫代码即可
linux下需要设置为无头模式
,驱动方式使用Service
1. 整合代码
爬虫代码命名为 kjl.py
# kjl.py
import datetime
from selenium import webdriver
import time
import random
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import qq_email
class KuJiaLe(object):
"""
酷家乐签到并获取一些数据
"""
def __init__(self):
self.url = 'https://www.kujiale.cn/signin?'
self.chromedriver = r'/home/pythonCode/codeDemo/chromedriver'
self.account = '666666' # 网站的账号
self.password = '666666' # 网站的密码
self.isSuccess = None # 是否爬取成功
self.integral = None # 积分
self.flag = None # 0 表示失败,1表示成功
self.start_time = time.time() # 统计爬取时间
self.failedCount = 0 # 统计失败次数
self.failedList = [] # 失败信息加入列表中
def get_result(self):
try:
s = Service(self.chromedriver)
chrome_options = Options()
chrome_options.add_argument("--headless") # => 为Chrome配置无头模式
chrome_options.add_argument('--no-sandbox') #
chrome_options.add_argument('--disable-gpu') # 禁用GPU加速
chrome_options.add_argument('--disable-dev-shm-usage')
driver = webdriver.Chrome(service=s,options=chrome_options)
driver.get(self.url)
time.sleep(random.uniform(1,2))
print('开始爬取某*乐 {}'.format(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S %A')))
account = WebDriverWait(driver,10).until(EC.presence_of_element_located((By.ID,"account"))).send_keys(self.account)
# 点击账号
password = WebDriverWait(driver,10).until(EC.presence_of_element_located((By.ID,"password"))).send_keys(self.password)
# 点击密码
login = WebDriverWait(driver,10).until(EC.presence_of_element_located((By.XPATH,'//button[text()="登录"]'))).click()
# 点击登录 ,开始登录
time.sleep(random.uniform(1,2))
driver.get('https://www.kujiale.cn/activities/jifengonglue')
# 跳转到签到
WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, "//*[@class='single-image']/div[3]"))).click()
# 点击签到
time.sleep(random.uniform(1,2))
driver.get('https://www.kujiale.cn/pcenter')
integral = WebDriverWait(driver,10).until(EC.presence_of_element_located((By.XPATH,'//*[@id="up-site-dash-board"]/div[1]/div/div[2]/div[1]/a/div/span'))).text
# 获取用户积分
self.flag = 1
self.isSuccess = '签到成功'
self.integral = integral
print('爬取成功..............')
except Exception as e:
print(e)
self.flag = 0
self.isSuccess = '签到失败'
self.failedList.append("签到失败,时间:" + datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S %A'))
self.failedCount += 1
if self.failedCount == 5:
self.flag = 1
return self.flag
print('爬取失败..............')
return self.flag
def start(self):
flag = self.get_result()
# print(flag)
if flag == 0: # 0 表示失败了
print('爬取失败 {} 次'.format(self.failedCount))
while True:
time.sleep(60) # 过60秒再次尝试登录
ret = self.get_result()
if ret == 1: # 5次后默认跳出
break
data = {
"now_time": datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S %A'),
"website": "某*乐 ",
"isSuccess": self.isSuccess,
"integral": str(self.integral),
"useTime":round(time.time() - self.start_time,2),
"failedInfo":{
"failedCount": self.failedCount,
"failedList":self.failedList
}
}
print(data)
print('数据整理完成...........')
return data
if __name__ == '__main__':
kjl = KuJiaLe()
data = kjl.start()
send_email_content = "时间:{} \n网站:{} \n是否成功: {} \n当前积分:{}\n获取积分用时:{}\n失败次数:{}\n失败详情:{}".format(data['now_time'],data['website'],data['isSuccess'],data['integral'],data['useTime'],data['failedInfo']['failedCount'],data['failedInfo']['failedList'])
email_theme = data['website'] + data['now_time']
e = qq_email.QQEmail()
e.send_email(email_theme,send_email_content)
2. 复制代码到linux
安装远程文件工具
yum install lrzsz
安装好后,将文件上传至服务器中。也可以直接将文件拖拽至 xshell中。Xshell使用教程
rz:表示上传文件 注意:上传只能一个一个,不能多选!!!!
sz: 表示将文件下载到本地 使用: sz + filename
当前文件结构
(seleniumEnv) [root@centos8-106 crawlCode]# tree
.
├── kjl.py
└── qq_email.py
0 directories, 2 files
3.6 Linux环境整体测试
在填好了邮箱等信息后,在linux
环境进行测试
python kjl.py
运行结果如下:
四、设置定时任务
4.1 编辑shell脚本来执行python 代码
1. 创建shell脚本
vim kjl.sh
2. 输入内容
#!/bin/bash
export PATH=$PATH:/usr/local/bin # 将/usr/local/bin/的环境导入系统变量中
source /home/pythonCode/virtualSet/seleniumEnv/bin/activate # 启动虚拟环境
python /home/pythonCode/crawlCode/kjl.py # 运行爬虫代码
3. 添加执行权限
chmod +x kjl.sh
4. 编写任务计划 crontab
Linux crontab是用来定期执行程序的命令。
当安装完成操作系统之后,默认便会启动此任务调度命令。
详细学习crontab:https://www.runoob.com/linux/linux-comm-crontab.html
5. 定制爬虫计划
终端输入命令,输入计划任务
crontab -e # 以当前用户添加任务计划,所以需要注意权限
# 输入内容 表示每隔2分钟执行一次
*/2 * * * * /home/pythonCode/crawlCode/kjl.sh >> /home/pythonCode/crawlCode/kjl.log 2>&1
也可以使用以下的任务计划
# 每天早上8点执行一次
00 08 * * * /home/pythonCode/crawlCode/kjl.sh >> /home/pythonCode/crawlCode/kjl.log 2>&1
6. 查看结果
使用tail -f /var/log/cron
命令查看crontab的运行结果,或者看日志也可以
tail -f /var/log/cron
(seleniumEnv) [root@centos8-106 crawlCode]# cat kjl.log
开始爬取某*乐 2022-03-19 14:08:05 Saturday
爬取成功..............
数据整理完成...........
开始发送邮件至: 920728039@qq.com
邮件发送成功
开始爬取某*乐 2022-03-19 14:10:05 Saturday
爬取成功..............
数据整理完成...........
开始发送邮件至: 920728039@qq.com
邮件发送成功
......
好了,本章完成了,欢迎大家在评论区留言,讨论。