• 古有愚公移山,今有冤种搬家~某人含泪写完了搬家脚本~~


    🌳 Long time no see

    相逢即是缘,来者皆是客,确定不看完再走?😁

    几日不见,如隔几日呀!近段因为课业繁忙,《小玩意儿》专栏停更了一段时间,实在是Sorry😬
    不知道为什么,总想着更新《小玩意儿》专栏的文章,可能是因为很多人喜欢,也有可能是因为写这类的文章比较放松,总而言之,就是喜欢……

    在这里插入图片描述
    不过写文章的过程是轻松的,打代码就不一样了,你看那头发,长得就不轻松……
    在这里插入图片描述

    有时候一个Bug出现,可以成功拿走我生命中的两个小时,最重要的是代码的测试,测试的过程是宛如……不说了不说了,它直接拿走我的生命!
    不过!经历了Bug无数次的疯狂抽打,这点对我来说不痛不痒(浅浅装一下)

    🍄收!回归主题

    今天给大家带来的是一个搬家脚本,搬家搬家,顾名思义就是搬家……
    在这里插入图片描述
    大概一周前,我无意间接触到文章搬家的这个“领域”,当时我还不知道搬家是啥,请原谅我没见过世面。后来慢慢了解,才知道“搬家”原来是将一个社区的文章搬到另一个社区中,悟了悟了!

    buling~的一下,突然就想到,诶,我之前写过一个CSDN文章转移到印象笔记中的一个脚本,那我是不是也可以从这个基础上做一个自动搬家的脚本,将CSDN的文章搬到其他社区发表,后来看了一下其他社区,就随机抽了一下,一只羊、两只羊、三只羊……就抽到了51CTO(不要问为什么,因为我也不知道)。

    咱们说干就干,搬!!!

    🍂 脚本代码的出生和结束

    根据之前写的文章:CSDN文章自动转移到印象笔记?一怒之下的我“揍”出了代码~
    本次的设计思路也差不多:
    (1)用户输入搬家的文章数,获取目标文章的链接和标题;
    (2)通过循环,进入每一篇文章,然后搬家;
    (3)将搬家成功的文章标题保存下载,写入excel文件中,以后在搬家的过程中就会读取已搬过的文章,筛选出未搬的文章,这就避免了重复搬家的情况。

    一一实现的过程请往下看👇

    🎃老朋友Get_cookie.py

    《小玩意儿》专栏的文章看来被Get_cookie.py下了咒,没错,又是它,实现自动登录的基石,想要了解可以看上边提到的文章哦!

    话不多说,直接贴代码:

    from selenium import webdriver
    from time import sleep
    import json
    if __name__ == '__main__':
      driver = webdriver.Chrome()
      driver.maximize_window()
      driver.get('https://passport.csdn.net/login?code=public')
      sleep(10)
    
      dictCookies = driver.get_cookies() # 获取list的cookies
      jsonCookies = json.dumps(dictCookies) # 转换成字符串保存
      with open('csdn_cookies.txt', 'w') as f:
        f.write(jsonCookies)
      print('cookies保存成功!')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    🌿真的要搬家了~

    本次搬家的文章主要是对Markdown文章进行搬家,如果不是Markdown编辑器编写的文章搬不了哦~

    🌱搬家工具介绍

    1. selenium模块:自动控制浏览器,实现对目标文章链接进行访问;
    2. time模块:控制基本进度,等待网页加载的作用;
    3. pyautogui:模拟键盘鼠标进行自动操作,主要进行读取保存的关键图片,根据图片查找屏幕中是否出现,出现后模拟键盘鼠标进行相应的操作;
    4. openpyxl模块:保存已搬家文章的标题,为以后筛选未搬家的文章;
    5. os模块:判断文件是否存在,不存在则创建;
    6. win32api和win32con模块:这两个模块搭配使用,实现鼠标自动滚动;
    7. json模块:获取Get_cookie.py文件运行后保存下的cookie值并转换格式,提供给selenium模块进行访问浏览器,达到自动登录的效果

    🌼搬家过程

    搬家准备
    • 搬家前准备截取以下图片并保存,这是针对本博主的情况进行截图,大家可根据自己的情况进行设定哦(主要提供思路,大家尽情发挥)
      在这里插入图片描述
      在这里插入图片描述
    开始搬家
    • 第一步:运行程序,输入搬家文章的数量并回车
      在这里插入图片描述
    • 第二步:等待网页加载,手动选择专栏并点击搜索
      在这里插入图片描述
    • 第三步:手动打开新的浏览器,打开51CTO博客,打开发文章,停留在发文章的那一页,然后将两个浏览器页面摆好,51CTO需要露出头像,CSDN需要在水平方向压缩至最小
      在这里插入图片描述
    • 第四步:在代码程序中输入1,回车,然后让屏幕出现如上图所示的样子
      在这里插入图片描述
    • 效果展示
      在这里插入图片描述
    • 保存的已搬家文章
      在这里插入图片描述

    🌾搬家源码

    提供思路,大家自由发挥哈~

    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
    import time
    import pyautogui
    import openpyxl
    import os
    import win32api
    import win32con
    import json
    
    
    class CSDN(object):
        def __init__(self, artical_num):
            # 实例化driver对象
            self.driver = webdriver.Chrome()
            self.artical_num = artical_num
            self.page_urls = [] # 存储文章url
            self.all_titles = [] # 存储文章的url
            self.To_transfer_url = [] # 存储要转移的文章url
            self.To_transfer_title = [] # 存储要转移的文章标题
            self.max_row = 0    # 设置最大行
    
    
    # --------------------------- 登录模块 ---------------------------
        def login(self):
            self.driver.get('https://mp.csdn.net/mp_blog/manage/article?')
    
            # 获取保存下的cookie值
            with open('csdn_cookies.txt', 'r', encoding='utf8') as f:
                listCookies = json.loads(f.read())
    
            # 往browser里添加cookies
            for cookie in listCookies:
                cookie_dict = {
                    'domain': '.csdn.net',
                    'name': cookie.get('name'),
                    'value': cookie.get('value'),
                    "expires": '',
                    'path': '/',
                    'httpOnly': False,
                    'HostOnly': False,
                    'Secure': False
                }
                self.driver.add_cookie(cookie_dict)
    
            self.driver.refresh()  # 刷新网页,cookies才成功
    
    # --------------------------- 文件操作模块 ---------------------------
        # 打开json文件,读取已经转移的文章
        def open_excel(self):
            self.f = openpyxl.load_workbook('./已转移文章.xlsx')
            self.sheet = self.f['Trans_artical']
            self.Transferred_titles = [i.value for i in self.sheet['A']]
            self.max_row = self.sheet.max_row
    
        # 保存已转移文章的标题
        def save_excel(self):
            for i in range(len(self.To_transfer_title)):
                self.sheet.cell(self.max_row+i+1, 1).value = self.To_transfer_title[i]
            self.f.save('./已转移文章.xlsx')
            print('文件保存成功!')
    
    # --------------------------- 文章转移模块 ---------------------------
        # 筛选要转移的文章
        def Filter_articles(self):
            n = 0
            for i in range(len(self.all_titles)):
                if self.all_titles[i] not in self.Transferred_titles:   # 如果获取的文章中的标题不存在已转移文章中
                    self.To_transfer_url.append(self.page_urls[i])     # 将要转移的文章url存到To_transfer_url中
                    self.To_transfer_title.append(self.all_titles[i])
                    if n == self.artical_num:
                        break
                    n += 1
    
        # 分析网页:获取文章url和标题
        def parse_page(self):
            """
            用户选择好分栏并点击后,输入1,程序继续运行
            :return:
            """
    
            # 等待内容管理加载完毕后点击
            WebDriverWait(self.driver, 1000).until(
                EC.presence_of_element_located((By.XPATH, '//ul[@role="menu"]/li/a[text()="内容管理"]'))
            )
            # 点击内容管理
            self.driver.find_element(By.XPATH, '//ul[@role="menu"]/li/a[text()="内容管理"]').click()
    
            print('\n请确认是否已选择专栏,点击搜索……')
    
            user1 = input('确认无误后请输入1,进行下一步操作……:')
    
            # 等待文章url加载
            WebDriverWait(self.driver, 1000).until(
                EC.presence_of_element_located((By.XPATH, '//p[@class="article-list-item-txt"]/a'))
            )
            time.sleep(2)
    
            while True:
                try:
                    # 获取文章元素
                    article = self.driver.find_elements(By.XPATH, '//p[@class="article-list-item-txt"]/a')
                    # 先添加文章url和文章标签
                    self.page_urls += [ele.get_attribute('href') for ele in article]
                    # 获取文章的标题
                    self.all_titles += [i.text for i in article]
                    # 点击下一页
                    self.driver.find_element(By.XPATH, '//*[@id="view-containe"]/div/div/div[4]/div/button[2]').click()
                    time.sleep(3)
                except:
                    break
            # 翻转
            self.page_urls = self.page_urls[::-1]
            self.all_titles = self.all_titles[::-1]
    
        def get_urls(self):
            for i in range(self.artical_num):
                self.driver.get(self.To_transfer_url[i])
    
                time.sleep(3)
                try:
                    # 获取富文本的“发送博客”元素
                    button = self.driver.find_element(By.XPATH, '//div[@id="moreDiv"]/div[10]/div/div/div[2]/button')
                    if button.is_enabled():
                        continue
                except: # 如果不是富文本则进行转移文章
                    self.move_to_51()
                    print(f'{self.To_transfer_title[i]} 搬家成功!')
    
    
        # 将CSDN中的文章转移到51cto
        def move_to_51(self):
            # 点击CSDN标题
            r = None
            while r is None:
                r = pyautogui.locateOnScreen('./photo_51/1.png')
            x, y = pyautogui.center(r)
            pyautogui.doubleClick(x, y)
            pyautogui.leftClick(x, y)
    
            # 复制标题
            pyautogui.hotkey('ctrl', 'c')
    
            # 点击印51cto的标题
            time.sleep(1)
            r = None
            while r is None:
                r = pyautogui.locateOnScreen('./photo_51/2.png')
            x, y = pyautogui.center(r)
            pyautogui.doubleClick(x, y)
    
            # 粘贴复制的文本
            pyautogui.hotkey('ctrl', 'v')
    
            # 点击CSDN文章的目录
            r = None
            while r is None:
                r = pyautogui.locateOnScreen('./photo_51/3.png')
            x, y = pyautogui.center(r)
            pyautogui.doubleClick(x, y)
    
            # 按下alt + a
            pyautogui.hotkey('ctrl', 'a')
            pyautogui.hotkey('ctrl', 'c')
    
            # 点击印象51cto的文章编辑处
            r = None
            while r is None:
                r = pyautogui.locateOnScreen('./photo_51/4.png')
            x, y = pyautogui.center(r)
            pyautogui.leftClick(x, y)
    
            # 粘贴
            pyautogui.hotkey('ctrl', 'v')
            time.sleep(1)
    
            # 点击“发布文章”
            r = None
            while r is None:
                r = pyautogui.locateOnScreen('./photo_51/5.png')
            x, y = pyautogui.center(r)
            pyautogui.leftClick(x, y)
    
            for i in range(4):   # 出现敏感词提醒
                r = pyautogui.locateOnScreen('./photo_51/19.png')
                if r is not None:
                    x, y = pyautogui.center(r)
                    pyautogui.leftClick(x, y)
                    break
    
            # 点击分类栏
            r = None
            while r is None:
                r = pyautogui.locateOnScreen('./photo_51/6.png')
            x, y = pyautogui.center(r)
            pyautogui.leftClick(x, y)
    
            # 点击分类
            r = None
            while r is None:
                r = pyautogui.locateOnScreen('./photo_51/7.png')
            x, y = pyautogui.center(r)
            pyautogui.leftClick(x, y)
    
            for i in range(1, 800):     # 向下滚动
                win32api.mouse_event(win32con.MOUSEEVENTF_WHEEL, 0, 0, -1)
            time.sleep(1)   # 等待两秒
    
            # 点击话题
            r = None
            while r is None:
                r = pyautogui.locateOnScreen('./photo_51/9.png')
            x, y = pyautogui.center(r)
            pyautogui.leftClick(x, y)
    
            # 选择话题
            r = None
            while r is None:
                r = pyautogui.locateOnScreen('./photo_51/10.png')
            x, y = pyautogui.center(r)
            pyautogui.leftClick(x, y)
    
            # 点击单图
            r = None
            while r is None:
                r = pyautogui.locateOnScreen('./photo_51/11.png')
            x, y = pyautogui.center(r)
            pyautogui.leftClick(x, y)
    
            # 点击添加图片选框
            r = None
            while r is None:
                r = pyautogui.locateOnScreen('./photo_51/12.png')
            x, y = pyautogui.center(r)
            pyautogui.leftClick(x, y)
    
            # 点击图片
            r = None
            while r is None:
                r = pyautogui.locateOnScreen('./photo_51/17.png')
            x, y = pyautogui.center(r)
            pyautogui.leftClick(x, y)
            # 按下回车键
            pyautogui.press('enter')
    
            # 点击“发布”
            r = None
            while r is None:
                r = pyautogui.locateOnScreen('./photo_51/14.png')
            x, y = pyautogui.center(r)
            pyautogui.doubleClick(x, y)
    
            try:    # 如果出现点击过快图片未加载完全的情况
                r = None
                for i in range(5):
                    r = pyautogui.locateOnScreen('./photo_51/18.png')
                    if r is not None:
                        pyautogui.doubleClick()
                    else:
                        break
            except:
                pass
            pyautogui.leftClick()
    
            # 点击首页
            r = None
            while r is None:
                r = pyautogui.locateOnScreen('./photo_51/15.png')
            x, y = pyautogui.center(r)
            pyautogui.doubleClick(x, y)
    
            # 点击写文章
            r = None
            while r is None:
                r = pyautogui.locateOnScreen('./photo_51/16.png')
            x, y = pyautogui.center(r)
            pyautogui.doubleClick(x, y)
    
    # --------------------------- 总流程控制 ---------------------------
        def run(self):
            self.login()    # 登录CSDN
            self.parse_page()  # 分析网页获取文章的标题和url
    
            if os.path.exists('./已转移文章.xlsx'):  # 判断如果存在json文件则打开文件进行筛选
                self.open_excel()    # 打开文件
                self.Filter_articles()  # 筛选url
    
            else:
                self.To_transfer_url = self.page_urls[:self.artical_num]   # 将获取的所有url给到self.To_transfer_url
                self.To_transfer_title = self.all_titles[:self.artical_num]
                # 创建文件
                self.f = openpyxl.Workbook()
                self.sheet = self.f.create_sheet('Trans_artical')
    
            self.get_urls()     # 调用self.get_urls()函数,将文章进行转移
            self.save_excel()    # 保存json文件
            self.driver.quit()
    
    
    if __name__ == '__main__':
        print('------ 搬家开始!请做好准备! ------')
        artical_num = int(input('\n请输入搬家文章的数量:'))
        time.sleep(2)
        csdn = CSDN(artical_num)
        csdn.run()
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296
    • 297
    • 298
    • 299
    • 300
    • 301
    • 302
    • 303
    • 304
    • 305
    • 306
    • 307
    • 308

    ⏰结束语

    非常感谢大家一直以来的支持💪 今天的分享就到这里啦!🚀

    如果喜欢这篇文章,那就旋个三连吧~ 点赞👍 收藏🌈 关注哦💖 您的支持,就是我更新的最大动力!感谢🌹

    “🚄See you next time💨”

    peace~

  • 相关阅读:
    springboot+java大学生新生入学报到报道系统+jsp004
    分类神经网络1:VGGNet模型复现
    java-net-php-python-jspm学生课堂学习状态查看系统计算机毕业设计程序
    Louvain算法在反作弊上的应用
    【场景化解决方案】OA审批与用友U9数据集成
    转行程序员,现实中真的容易吗?
    新手使用php7的加密方法来保护代码的安全性
    深度学习中端到端的概念
    C#运算符重载
    第七章:java Object类
  • 原文地址:https://blog.csdn.net/Oh_Python/article/details/127713518