Python3爬虫实战 — 模拟登陆CSDN并自动保存文章

Python3爬虫实战 — 模拟登陆CSDN并发布或保存文章

> 爬虫时间:2020-08-31
> 请求链接:https://passport.csdn.net/login?code=public
> 实现目标:模拟登陆CSDN,自动保存文章
> 涉及知识:自动化测试工具 Selenium 的使用
> 完整代码:https://github.com/dateolive/python-crawler/tree/master/csdn
> 学习过程中的爬虫GitHub库:https://github.com/dateolive/python-crawler

爬虫思路如下:

  • 分析登录页面,csdn的登录页面一开始是微信扫码登录,我们需要通过XPath找到账号密码登录的点击按钮,实现模拟点击跳转到账号密码登录的页面
  • 之后使用Selenium工具模拟输入账号密码,并点击登录(我在写这个爬虫的时候,csdn没有验证码验证,如果后面需要验证码了,可以仿照我的其他文章对验证码识别对抗即可
  • 登录之后,找到创作中心的按钮,点击跳转,之后再点击markdown编辑器按钮,此时浏览器会打开一个新的标签,这个时候我们需要更新下当前句柄,通过browser.switch_to.window(n[-1])选择新打开的页面,后面的操作在这个窗口实现
  • 此时我们已经进入编写文章,找到对应的标题输入框和正文输入框,我们首先应该先把这两个输入框的内容清空,然后再输入对应信息,最后,我们可以选择点击保存草稿,也可以选择发布文章,我这里只写了保存草稿,发布文章的后续操作也差不多,就是一直模拟点击即可

一.准备工作

忘记密码了,重新修改密码QAQ。。😂

二.爬虫构建

1.初始化函数

def __init__(self):
    self.url = 'https://passport.csdn.net/login?code=public'
    self.browser = webdriver.Chrome()
    self.browser.maximize_window()
    self.wait = WebDriverWait(self.browser, 20)
    self.username = USERNAME
    self.password = PASSWORD
    self.title=TITLE
    self.article=ARTICLE
这里定义了发起请求的url、用户名、密码,文章标题,文章正文等全局变量,实例化 Chrome 浏览器、设置浏览器分辨率最大化、用户名、密码、同时也设置等待超时

2.登录函数

def open(self):
    """
    打开网页输入用户名密码
    :return: None
    """
    self.browser.get(self.url)
    #进去之后,先要点击账号密码登录,跳过微信登录的页面
    self.browser.find_element_by_xpath('//*[@id="app"]/div/div/div[1]/div[2]/div[5]/ul/li[2]/a').click()
    time.sleep(2)
    email = self.wait.until(EC.presence_of_element_located((By.ID, 'all')))
    password = self.wait.until(EC.presence_of_element_located((By.ID, 'password-number')))
    email.send_keys(self.username)
    time.sleep(2)
    password.send_keys(self.password)
    login_btn = self.wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, 'button.btn.btn-primary')))
    # 随机暂停几秒
    time.sleep(random.random() * 3)
    # 点击登陆按钮
    login_btn.click()
通过XPath找到账号密码登录的点击按钮,实现模拟点击跳转到账号密码登录的页面,等待账号输入框和密码输入框对应的 ID 节点加载出来,然后获取对应节点,其中账号输入框 id="all",密码输框id="password-number",通过调用 send_keys() 方法输入账号和密码,接着获取登录按钮 ,设置暂停时间,最后调用 click() 方法实现登录按钮的点击。

3.自动化编写文章

def write(self):
    time.sleep(3)
    self.browser.find_element_by_xpath('//*[@id="csdn-toolbar"]/div/div[3]/div[1]/a').click()
    time.sleep(2)
    self.browser.find_element_by_xpath('//*[@id="app"]/div/div[1]/div[1]/div[1]/a[1]/span').click()
    time.sleep(2)
    n = self.browser.window_handles  # 这个时候会生成一个新窗口或新标签页的句柄,代表这个窗口的模拟driver
    print('当前句柄: ', n)  # 会打印所有的句柄
    self.browser.switch_to.window(n[-1])
    delete1=self.wait.until(EC.presence_of_element_located((By.XPATH,'/html/body/div[1]/div[1]/div[1]/div/div[2]/input')))
    delete1.clear()
    time.sleep(1)
    title=self.wait.until(EC.presence_of_element_located((By.XPATH,'/html/body/div[1]/div[1]/div[1]/div/div[2]/input')))
    title.send_keys(self.title)
    time.sleep(2)
    delete2=self.wait.until(EC.presence_of_element_located((By.XPATH,'/html/body/div[1]/div[1]/div[2]/div/div[2]/div[1]/div[2]/pre')))
    delete2.clear()
    time.sleep(2)
    message=self.wait.until(EC.presence_of_element_located((By.XPATH,'/html/body/div[1]/div[1]/div[2]/div/div[2]/div[1]/div[2]/pre')))
    message.send_keys(self.article)
    keep=self.wait.until(EC.presence_of_element_located((By.XPATH,'/html/body/div[1]/div[1]/div[1]/div/div[3]/button[1]')))
    keep.click()
登录之后,通过XPath找到创作中心的按钮,点击跳转,之后再点击markdown编辑器按钮,此时浏览器会打开一个新的标签,这个时候我们需要更新下当前句柄,通过browser.switch_to.window(n[-1])选择新打开的页面,找到对应的标题输入框和正文输入框,我们首先应该先把这两个输入框的内容清空,然后再输入对应信息,点击保存草稿

三.爬虫完整代码

import random
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

USERNAME = '2448282543@qq.com'
PASSWORD = '密码'
TITLE='模拟登录csdn并发布文章'
ARTICLE='这是一篇水文,爬虫测试'

class CrackTouClick():
    def __init__(self):
        self.url = 'https://passport.csdn.net/login?code=public'
        self.browser = webdriver.Chrome()
        self.browser.maximize_window()
        self.wait = WebDriverWait(self.browser, 20)
        self.username = USERNAME
        self.password = PASSWORD
        self.title=TITLE
        self.article=ARTICLE


    def open(self):
        """
        打开网页输入用户名密码
        :return: None
        """
        self.browser.get(self.url)
        #进去之后,先要点击账号密码登录,跳过微信登录的页面
        self.browser.find_element_by_xpath('//*[@id="app"]/div/div/div[1]/div[2]/div[5]/ul/li[2]/a').click()
        time.sleep(2)
        email = self.wait.until(EC.presence_of_element_located((By.ID, 'all')))
        password = self.wait.until(EC.presence_of_element_located((By.ID, 'password-number')))
        email.send_keys(self.username)
        time.sleep(2)
        password.send_keys(self.password)
        login_btn = self.wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, 'button.btn.btn-primary')))
        # 随机暂停几秒
        time.sleep(random.random() * 3)
        # 点击登陆按钮
        login_btn.click()
    def write(self):
        time.sleep(3)
        self.browser.find_element_by_xpath('//*[@id="csdn-toolbar"]/div/div[3]/div[1]/a').click()
        time.sleep(2)
        self.browser.find_element_by_xpath('//*[@id="app"]/div/div[1]/div[1]/div[1]/a[1]/span').click()
        time.sleep(2)
        n = self.browser.window_handles  # 这个时候会生成一个新窗口或新标签页的句柄,代表这个窗口的模拟driver
        print('当前句柄: ', n)  # 会打印所有的句柄
        self.browser.switch_to.window(n[-1])
        delete1=self.wait.until(EC.presence_of_element_located((By.XPATH,'/html/body/div[1]/div[1]/div[1]/div/div[2]/input')))
        delete1.clear()
        time.sleep(1)
        title=self.wait.until(EC.presence_of_element_located((By.XPATH,'/html/body/div[1]/div[1]/div[1]/div/div[2]/input')))
        title.send_keys(self.title)
        time.sleep(2)
        delete2=self.wait.until(EC.presence_of_element_located((By.XPATH,'/html/body/div[1]/div[1]/div[2]/div/div[2]/div[1]/div[2]/pre')))
        delete2.clear()
        time.sleep(2)
        message=self.wait.until(EC.presence_of_element_located((By.XPATH,'/html/body/div[1]/div[1]/div[2]/div/div[2]/div[1]/div[2]/pre')))
        message.send_keys(self.article)
        keep=self.wait.until(EC.presence_of_element_located((By.XPATH,'/html/body/div[1]/div[1]/div[1]/div/div[3]/button[1]')))
        keep.click()


    def crack(self):
        """
        破解入口
        :return: None
        """
        self.open()
        self.write()

if __name__ == '__main__':
    crack = CrackTouClick()
    crack.crack()

四.GIF登录图

点赞

发表评论

昵称和uid可以选填一个,填邮箱必填(留言回复后将会发邮件给你)
tips:输入uid可以快速获得你的昵称和头像