Loading [MathJax]/extensions/MathZoom.js

自动登录脚本

有感于每天签到,用selenium、chromedriver和python配置了一个自动登录脚本

下载selenium和chromedriver

  1. 我在win10上使用了conda,可以通过
    install selenium ```来安装,也可以
    1
    2
    3
    通过 ``` pip install selenium ``` 来安装
    1. 从[官网](http://chromedriver.chromium.org/downloads)下载chromedriver,win10
    下安装chromedriver,解压到python.exe所在的文件夹。Linux下进行如下操作

sudo apt-get install unzip
unzip chromedriver_linux64.zip

chmod +x chromedriver
sudo mv -f chromedriver /usr/local/share/chromedriver
sudo ln -s /usr/local/share/chromedriver /usr/local/bin/chromedriver
sudo ln -s /usr/local/share/chromedriver /usr/bin/chromedriver

1
2
3
4
5
6
7
8
9
linux安装引自 [YasinQiu的博客](https://blog.csdn.net/pangtouyu_qy/article/details/80282795) 

## 测试启动chrome
1. 这里给出一个比较详细的[selenium解释](https://cuiqingcai.com/2599.html)。以下是我的学习记录
2. win10下会启动chrome,因此比较容易上手。使用接收器逐行运行以下代码:
```python
from selenium import webdriver
browser = webdriver.Chrome()
browser.get('http://www.google.com/')

简单三行就可以了。此时会启动chrome浏览器并打开网页。
  1. 选择元素并模拟点击和输入文本
    我一般使用xpath来选择元素。在打开的chrome上按F12,弹出来的窗口上点选择元素
    (或者按Ctrl+Shift+c),然后去选择元素。右键源码里的蓝色源码,Copy->Copy XPath。
    得到xpath。得到的xpath示例:

    1
    2
    3
    4
    5
    6
    ```python
    from selenium.webdriver.common.keys import Keys
    elem = driver.find_element_by_xpath('//*[@id="ks-component324"]/div/input')
    elem.send_keys("some text") #文本
    elem.send_keys(Keys.ENTER) #回车
    elem.click() #左键单击

  2. 最后使用

    ```关闭浏览器
    1
    2
    3
    4
    5
    6
    7
    5. 模拟移动端chrome
    ``` python
    from selenium import webdriver
    mobileEmulation = {'deviceName': 'iPhone X'}#模拟移动端
    options = webdriver.ChromeOptions()
    options.add_experimental_option('mobileEmulation', mobileEmulation)
    driver = webdriver.Chrome(chrome_options=options)

模拟登录并获取保存cookie

  1. 以微博(可以替换为你要签到的网站)为例,打开浏览器进入网页:

    1
    2
    3
    from selenium import webdriver
    driver = webdriver.Chrome()
    driver.get('http://weibo.com')

    此时chrome会打开网页,这时可以通过手动方式进行登录。

  2. 登录成功后保存cookie

    1
    2
    3
    4
    5
    6
    import json
    #获取cookie
    cookie=driver.get_cookies()
    #保存到文件
    with open('e:\\weibo.json','w') as f:
    f.write(json.dumps(cookie))
  3. 关闭webdriver

    1
    driver.close()

模拟登录签到

  1. 打开所签到网站并添加cookie,刷新网页

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    import json
    from selenium import webdriver

    driver = webdriver.Chrome()
    driver.get('http://yourweb.com')
    #有时服务器打开网页过久,而实际上不需要把网页全部加载出来
    driver.set_page_load_timeout(10)
    #try:
    # driver.get(url)
    #except:
    # print("stop load")
    # try:
    # driver.execute_script("window.stop()")
    # except:
    # pass
    #添加cookie
    driver.delete_all_cookies()
    with open('cookie.json','r') as f:
    cookie_list=json.loads(f.read())
    for cookie in cookie_list:
    driver.add_cookie(cookie)
    #重新get网页
    driver.get('http://yourweb.com')
  2. 找到”签到”元素,并单击

    1
    2
    elem=driver.find_element_by_xpath('//*[@id="Pl_Core_StuffHeader__1"]/div/div[2]/div/div[3]/div/div[3]/a')
    elem.click()

将脚本配置到服务器上

  1. 服务器安装chrome。(chromedirver安装如前所述)

    • 下载deb文件
    • 安装软件
      1
      2
      sudo dpkg -i google-chrome-stable_current_amd64.deb
      sudo apt-get install -f
  2. 脚本中的配置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    mobileEmulation = {'deviceName': 'iPhone X'}#配置为移动浏览器,非必须
    options = webdriver.ChromeOptions()
    options.add_experimental_option('mobileEmulation', mobileEmulation)#配置为移动浏览器,非必须
    options.add_argument('--headless')
    options.add_argument('--disable-gpu')#视自身情况,可以注释掉
    options.add_argument('--disable-dev-shm-usage')
    options.add_argument('--no-sandbox')
    #有些网站不加这一条会出现"element not interactable"
    options.add_argument('--window-size=1920,1080')
    driver = webdriver.Chrome(chrome_options=options)

    如上可以启动浏览器了,之后的操作与win相同

  3. 将win10上的脚本补到上文之后,注意json文件的位置
  4. 添加到crontab 每日定时任务中

将输出信息发送给邮箱

  1. 将脚本错误信息重定向到输出
    0 是标准输入(STDIN),1 是标准输出(STDOUT),2 是标准错误输出(STDERR)
    2>&1表示将标准错误重定向到标准输出中,而tee从标准输入读取并写到标准输出中。将输出重定向到/dev/null表示不在屏幕上显示输出。
    因此使用
    1
    python check_in.py 2>&1 | tee error.txt >/dev/null

可以将输出写入到error.txt中

  1. 使用python将error.txt发送到邮箱,可以参考这两个教程
    1. 简单三步,用 Python 发邮件 - Crossin的文章 - 知乎
    2. Python SMTP发送邮件
    3. 我的脚本,这里直接读error.txt作为正文了,也可以作为附件,或者使用管道直接将上一个脚本的输出作为输入(不需要写error.txt了)
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      import smtplib
      from email.mime.text import MIMEText
      from email.header import Header
      mail_host="smtp.163.com"
      #用户名为邮箱的前缀
      mail_user="2******8"
      #密码,163为授权码
      mail_pass="******"
      sender='2******8@163.com'
      #使用列表可以发送多个收件人
      recevers=['1***2@qq.com']
      with open('error.txt','r') as f:
      text=f.read()
      message=MIMEText(text,'plain','utf-8')
      message['Subject']='自动登录签到反馈'
      message['From']=sender
      message['To']=recevers[0]
      smtpObj=smtplib.SMTP()
      smtpObj.connect(mail_host,25)
      smtpObj.login(mail_user,mail_pass)
      smtpObj.sendmail(sender,recevers,message.as_string())
      smtpObj.quit()

定时任务

  1. 编写shell脚本

    1
    2
    python check_in.py
    python send_mail.py
  2. crontab设置自动运行

    1
    2
    crontab -e#阅读提示示例命令就可以写出来了
    0 6 * * * /home/check.sh

后记

我在网上看到有人讲cookie可能几十天就失效了需要更新,而且xpath也有可能会更新,所以关注邮箱反馈信息。刚开始打算使用linux的mail来发邮件,但还是很复杂,没有搞定,果然还是python简单。服务器端貌似可以很轻易的判断出这个是selenium而非人工操作,有一个变量window.navigator.webdriver(在console里运行)在手工打开的浏览器里未定义,但在selenium里是true,这个好像要重新修改编译浏览器源码才行。