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登录图