爬虫-华为云空间备忘录导出到docx-selenium控制浏览器行为-python数据处理

news2025/4/8 3:47:38

背景+适用情况介绍

老的荣耀手机属于华为云系统,家里人换了新荣耀手机属于荣耀云系统无法通过云空间将备忘录转移到新手机,不想让他们一个一个搞,于是整了一晚上想办法爬取下来。从网页抓取下来,然后存到docx文档中(包括文字和图片,别的形式的内容请举一反三) 多行图片多行文字sample:
演示gif
本方法Cons:不能复制到荣耀云里,因为捣了半天这荣耀云根本就没有除了手机之外可以访问的方法

别的思路

手机内部自动化保存为文档后处理
华为手机备忘录批量导出txt╳ 全自动版 ╳By 免ROOT自动化助手
cons:这个up是导出一条删除一条,我不想删除,它有for循环但是要付费,付费倒不是啥别太贵就行毕竟人家做的工具,但是一看还要注册登录,,,

fiddler抓包方式抓所有笔记页面
华为手机备忘录批量导出文字和图片
cons:看了一下需要手动一个一个点笔记,不想动了

前置准备

  • 首先确定老手机在设置的主账号登录进去或者注册是华为云,让家里注册了一下,然后打开同步把数据同步到云端,登录华为云空间可以看到所有的备忘录,点进去记录第一个备忘录的URL后面都要用
  • 需要chrome(查看版本:右上角三个点-help-about)和版本匹配的chromedriver(别的可以控制浏览器控件如firefox也可以,我这样用)
    chromedriver.exe的目录需要加入环境变量path,cmd运行 chromedriver 可测试,如果调用里自定义位置可以尝试path参数,库接口已更新与文档不匹配
  • python环境

代码步骤

in simulate

  • 第一次扫码登录,登录完毕python控制台任意enter继续,自动保存cookies到cookies.json后续不用登录

  • 手动浏览器f12分析元素可知中间一列是每页链接列表,右边一列是点击后的笔记标题时间内容,找到dom树下到达这个元素的路径,可覆盖到元素然后右键复制path-xpath得到,示例如下:
    中间目录内容

  • 对每个元素点击,滑动到下一个(必须滑动,为了点击下一个做准备,否则直接代码点击超出视窗的元素无法加载右侧笔记内容)

  • 相关知识链接
    – selenium-python document
    – xPath examples 注意dom css中序数是从1开始
    – 滑动界面外的元素问题
    – 获取元素标签内容和属性值例子

  • 根据xpath提取标题,时间,内容,内容由分析可知是一个一个div行叠加的,图文都是在行中,所以内循环提取一行一行内容

  • 内循环-图:request无法下载?控制浏览器下载,从默认目录移动到当前/img下并加上jpg后缀(因为看了一下上传只能传jpg,下载时候看了一下都可以用jpg打开)图文件名保存在列表中备用(应该没有重复的)

  • 重新组成数据格式如下,or whatever you want,然后存到result.json
    – [title0, time0, [content0 line0 text, content0 line1 img name, …]]
    – [title1, …]

in result_to_doc

  • 很简单一行一行写入
  • 相关链接
    – python-docx quick start 注意docx库实际要装的是python-docx,如果import docx有错看装的对不对

project结构以及代码

在这里插入图片描述

simulate.py

import json
import os
import shutil
import time

import requests as requests
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By


def login_and_save_to_cookies(driver, url):
    # driver = webdriver.Chrome()
    driver.get(url)
    val = input("Manually login now. Enter anything if finished")
    # time.sleep(20)  # Let the user actually see something!
    cookies = driver.get_cookies()
    # 转换成字符串保存
    json_cookie = json.dumps(cookies)
    # 保存到txt文件
    with open('cookies.json', 'w') as f:
        f.write(json_cookie)
    print('cookies保存成功!')

def login_with_cookies(driver):
    with open('cookies.json','r',encoding='utf8') as f:
        cookies = json.loads(f.read())
    # 给浏览器添加cookies
    for cookie in cookies:
        driver.add_cookie(cookie)
    # 刷新网页,cookies才会成功,后面我们直接跳转就不用刷新了
    # driver.refresh()

if __name__ == '__main__':

    driver = webdriver.Chrome()

    # 笔记的第一页url,后面需要用到
    url = 'https://cloud.huawei.com/home#/notepad/note/allNote/note/xxxxxxxxxxxxxxxxxxxxxxx'

    # 加载已有cookies之前至少得先访问一遍
    driver.get(url)
    time.sleep(5)  # 需要等待加载完

    # 切换成中文
    language_button = driver.find_element(By.XPATH,'//*[@id="Cloudlogin"]/div[1]/div[1]/div[2]/a[1]/span[1]')
    ActionChains(driver).click(language_button).perform()  # single click
    chinese_button = driver.find_element(By.XPATH,'//*[@id="scroller"]/ul/li[65]/div')
    ActionChains(driver).click(chinese_button).perform()  # single click
    time.sleep(5)

    val = input("If using existing cookies, type 'n', manually login type anything else")
    if val != 'n':
        login_and_save_to_cookies(driver, url)
    login_with_cookies(driver)
    time.sleep(5)
    driver.get(url)
    time.sleep(5)
    # driver.find_element(By.)

    note_center_items = driver.find_elements(By.CLASS_NAME, "note_item")

    note_titles = []
    note_times = []
    note_contents = []

    chrome_download_directory = "C:\\Users\\xxxxxxxxxxxxxx\\Downloads\\"  # 浏览器默认下载路径
    img_store_directory = "./img/"  # 都需要以/结尾以便后面拼接

    for note_center_item in note_center_items:
        # print(note_center_item.get_attribute("autokey"))
        ac = note_center_item
        # ActionChains(driver).scroll_to_element(ac).perform()
        ActionChains(driver).click(ac).perform()  # single click
        driver.execute_script("arguments[0].scrollIntoView(true);", ac)  # 必须滑动,不然点击视窗外的元素无法加载右侧笔记内容
        time.sleep(5)
        title_element = driver.find_element(By.XPATH,
                                           '//*[@id="note_title_editor"]/div/div[6]/div[1]/div/div/div/div[5]/pre/span')
        time_element = driver.find_element(By.XPATH,
                                           '//*[@id="app"]/div[6]/div[3]/div/div[1]/div[4]/div[2]/div/span[1]')
        content_multiline_container_element = driver.find_element(By.XPATH,
                                              '//*[@id="note_detail_editor"]/div/div[6]/div[1]/div/div/div/div[5]')
        content_singleline_containers = content_multiline_container_element.find_elements(By.XPATH, './div')
        note_content = []
        for i in range(len(content_singleline_containers)):
            content_singleline_container = content_singleline_containers[i]
            try:
                # is an image
                img_element = content_singleline_container.find_element(By.XPATH, './div/div/img')
                img_src = img_element.get_attribute("src")

                # 用浏览器下载,这里request好像不行
                driver.get(img_src)
                # cur_img = requests.get(img_src)
                # note_content.append(cur_img)

                # 等待下载完
                time.sleep(3)

                # 转移,加jpg后缀因为这里都是jpg格式
                downloaded_file_name = img_src.split("/")[-1]
                shutil.move(chrome_download_directory + downloaded_file_name, img_store_directory)
                os.rename(img_store_directory + downloaded_file_name, img_store_directory + downloaded_file_name + '.jpg')
                note_content.append(downloaded_file_name + '.jpg')  # 标记位置
            except:
                # is text
                note_content.append(content_singleline_container.text)  # 可以直接获取最里面的值, 也可以通过./pre/span/span获取最里面的元素再获取text

            # 如果全是文字可以直接合并成段落
            # if i < len(content_singleline_containers) - 1:
            #     note_content += "\n"
        note_title = title_element.text
        note_time = time_element.text

        note_titles.append(note_title)
        note_times.append(note_time)
        note_contents.append(note_content)
        print(note_title)
        print(note_time)
        print(note_content)

    print(len(note_titles), len(note_times), len(note_contents))
    result = []
    for i in range(len(note_titles)):
        result.append([note_titles[i], note_times[i], note_contents[i]])
    with open('result.json', 'w') as f:
        json.dump(result, f)

    # f = open("result.txt", "w")
    # for i in range(len(note_times)):
    #     f.write(note_times[i])
    #     f.write(note_contents[i])
    #     f.write("\n")
    # f.close()

    # time.sleep(20)

result_to_doc.py

import json

from docx import Document
from docx.shared import Inches

document = Document()

with open('result.json', 'r') as f:
    data_json = json.load(f)

img_store_directory = "./img/"
for note_title, note_time, note_content in data_json:
    if len(note_title) > 0:
        # 这里很多都是空标题所以如果空就不写入
        document.add_paragraph(note_title)
    document.add_paragraph(note_time)
    for note_content_line in note_content:
        if note_content_line.split('.')[-1] == 'jpg':
            # is an image
            document.add_picture(img_store_directory + note_content_line, width=Inches(5))
        else:
            document.add_paragraph(note_content_line)
    document.add_paragraph("\n")

document.save('备忘录.docx')

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1452475.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

不花一分钱,在 Mac 上跑 Windows(M1/M2 版)

这是在 MacOS M1 上体验最新 Windows11 的效果&#xff1a; VMware Fusion&#xff0c;可以运行 Windows、Linux 系统&#xff0c;个人使用 licence 免费 安装流程见 &#x1f449; https://zhuanlan.zhihu.com/p/452412091 从申请 Fusion licence 到下载镜像&#xff0c;再到…

phpstrom创建thinkphp项目

安装php和composer 参考 安装phpstrom 创建项目 查看thinkphp版本 https://packagist.org/packages/topthink/think 打开所在项目编辑配置 即可调试运行

软件工程师,超过35岁怎么办

概述 随着科技行业的飞速发展&#xff0c;软件开发工程师的职业道路充满了各种机遇和挑战。对于已经在这个行业摸爬滚打了十多年的软件开发工程师来说&#xff0c;当他们步入35岁这个年纪时&#xff0c;可能会感到一些迷茫和焦虑。许多人担忧&#xff0c;在以创新、活力、快速迭…

MongoDB从入门到实战之.NET Core使用MongoDB开发ToDoList系统(2)-Swagger框架集成

Swagger是什么&#xff1f; Swagger是一个规范且完整API文档管理框架&#xff0c;可以用于生成、描述和调用可视化的RESTful风格的 Web 服务。Swagger 的目标是对 REST API 定义一个标准且和语言无关的接口&#xff0c;可以让人和计算机拥有无须访问源码、文档或网络流量监测就…

MySQL篇之覆盖索引

一、定义 覆盖索引是指查询使用了索引&#xff0c;并且需要返回的列&#xff0c;在该索引中已经全部能够找到。 二、例子 1. id为主键&#xff0c;默认是主键索引。 2. name字段为普通索引。 select * from tb_user where id 1 覆盖索引 select id&#xff0c;na…

Codeforces Round 486 (Div. 3)

目录 A. Diverse Team B. Substrings Sort C. Equal Sums D. Points and Powers of Two E. Divisibility by 25 F. Rain and Umbrellas A. Diverse Team 找出不重复的同时存下下标即可&#xff0c;依次遍历map判断重复最后判断数量即可 void solve(){cin>>n>>…

太炸了!Sora深夜发布!网友:我要失业了

2022年末&#xff0c;OpenAI聊天机器人ChatGPT的面世无疑成为了引领人工智能浪潮的标志性事件&#xff0c;宣告了新一轮科技革命的到来。无论是聊天娱乐、教育学习&#xff0c;还是工作生产、医疗健康等领域&#xff0c;人工智能正以前所未有的速度渗透到我们生活的方方面面。 …

ClickHouse--10--临时表、视图、向表中导入导出数据

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 1.临时表1.1 特征1.2 创建一个临时表 2.视图2.1 普通视图2.2 物化视图 3.向表中导入导出数据3.1 案例 1.临时表 1.1 特征 ClickHouse 支持临时表&#xff0c;临时表…

【网站项目】154智能无人仓库管理

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

【图论】2-SAT

参考资料&#xff1a;2-SAT学习笔记 什么是2-SAT问题呢&#xff1f; (a∨b∨c)∧(a∨b∨c)∧(a∨b∨c)&#xff0c;给出一个类似于这样的式子&#xff0c;让你找出满足条件的一个解&#xff0c;这样的问题就是SAT问题&#xff0c;因为每一个括号内都有三个被限制的变量&#…

人工智能学习与实训笔记(七):神经网络之模型压缩与知识蒸馏

人工智能学习笔记汇总链接&#xff1a;人工智能学习与实训笔记汇总-CSDN博客 本篇目录 七、模型压缩与知识蒸馏 7.1 模型压缩 7.2 知识蒸馏 7.2.1 知识蒸馏的原理 7.2.2 知识蒸馏的种类 7.2.3 知识蒸馏的作用 七、模型压缩与知识蒸馏 出于对响应速度&#xff0c;存储大…

算法刷题:无重复字符的最长字串

无重复字符的最长字串 .题目链接题目详情算法原理题目解析滑动窗口定义指针进窗口判断出窗口更新结果 我的答案 . 题目链接 无重复字符的最长字串 题目详情 算法原理 题目解析 首先,为了使字符串遍历的更加方便,我们选择将字符串转换为数组 题目要求子串中不能有重复的字符…

MessageQueue --- RabbitMQ

MessageQueue --- RabbitMQ RabbitMQ IntroRabbitMQ 核心概念RabbitMQ 分发类型Dead letter (死信)保证消息的可靠传递 RabbitMQ Intro 2007年发布&#xff0c;是一个在AMQP&#xff08;高级消息队列协议&#xff09;基础上完成的&#xff0c;可复用的企业消息系统&#xff0c;…

Pandas:DataFrame的完整指南【第82篇—DataFrame】

Pandas&#xff1a;DataFrame的完整指南 Pandas是Python中最流行的数据处理库之一&#xff0c;而其中的DataFrame对象是数据处理的核心。DataFrame为我们提供了一个强大而灵活的数据结构&#xff0c;使得数据的清洗、分析和可视化变得更加简便。在本文中&#xff0c;我们将深入…

旅游出门千万别忘带这些!花的不多,享受翻倍!随身wifi看这篇,高性价比高口碑随身wifi推荐

春节长假&#xff0c;大家都去哪儿玩了呢&#xff1f;我反正带着我的小背包&#xff0c;走遍了祖国的大好河山&#xff01; 得益于之前几次长假出行的经验&#xff0c;这次出行体验十分完美。除了详细完备的出行攻略&#xff0c;还有就是一些出行好物&#xff0c;虽然不起眼&am…

采购平台架构设计和实现的实战总结

当代企业日益重视采购管理的有效性和高效性&#xff0c;而采购平台的架构设计和实现则成为实现这一目标的关键。本文将探讨采购平台架构设计的重要性、关键原则以及实施过程中需要考虑的要点&#xff0c;帮助企业构建强大的采购平台&#xff0c;提升采购管理效率和效果。 ### 1…

在PyTorch中,如何查看深度学习模型的每一层结构?

这里写目录标题 1. 使用print(model)2. 使用torchsummary库3.其余方法&#xff08;可以参考&#xff09; 在PyTorch中&#xff0c;如果想查看深度学习模型的每一层结构&#xff0c;可以使用print(model)或者model.summary()&#xff08;如果你使用的是torchsummary库&#xff0…

Arrays工具类的常见方法总结

一、Arrays.asList( ) 1、作用 Arrays.asList( )可以将一个数组以集合的形式传入一个集合对象。通常用来将一组元素全部添加到集合中。 2、参数及返回值 参数&#xff1a;一组动态参数 返回值&#xff1a;List<T>集合 3、应用举例 List<String> boyListArra…

什么是智慧公厕,智慧公厕有哪些功能

1.什么是智慧公厕&#xff1f; 随着智慧城市的快速发展&#xff0c;公共厕所作为城市基础设施的一部分&#xff0c;也在逐步升级转型。那么&#xff0c;什么是智慧公厕&#xff1f;智慧公厕作为智慧城市的重要组成部分&#xff0c;将公共厕所的建设、设计、使用、运营和管理等…

深入解析鸿蒙系统的页面路由(Router)机制

鸿蒙系统以其独特的分布式架构和跨设备的统一体验而备受瞩目。在这个系统中&#xff0c;页面路由&#xff08;Router&#xff09;机制是连接应用各页面的关键组成部分。本文将深入探讨鸿蒙系统的页面路由&#xff0c;揭示其工作原理、特点以及在应用开发中的实际应用。 1. 实现…