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

背景+适用情况介绍

老的荣耀手机属于华为云系统,家里人换了新荣耀手机属于荣耀云系统无法通过云空间将备忘录转移到新手机,不想让他们一个一个搞,于是整了一晚上想办法爬取下来。从网页抓取下来,然后存到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')

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

WordPress主题YIA移动端文章页的面包屑不显示怎么办?

平时我们一般都会在文章页导航菜单下方显示面包屑&#xff0c;类似于“当前位置&#xff1a;boke112百科 WordPress 正文”。平时用浏览器调试站点的时候&#xff0c;在Edge浏览器的“切换设备仿真”中&#xff0c;不管是选择什么设备都会显示面包屑。具体如下图所示&#xf…

四种mfc140u.dll丢失的解决方法,有效恢复mfc140u.dll丢失

mfc140u.dll文件的重要性&#xff0c;当系统中出现mfc140u.dll丢失的情况时&#xff0c;可能会导致一系列问题和影响。因此&#xff0c;保持mfc140u.dll文件的完整性对于系统和应用程序的稳定运行至关重要。一旦出现mfc140u.dll文件丢失的情况&#xff0c;我们需要采取有效的方…

Karnaugh map (卡诺图)

【Leetcode】 289. Game of Life According to Wikipedia’s article: “The Game of Life, also known simply as Life, is a cellular automaton devised by the British mathematician John Horton Conway in 1970.” The board is made up of an m x n grid of cells, wh…

mfc140u.dll文丢失导致应用程序无法正常,有哪些解决办法

mfc140u.dll是Microsoft Foundation Classes&#xff08;MFC&#xff09;的一个重要组件&#xff0c;它提供了许多用于开发Windows应用程序的功能和工具。然而&#xff0c;当系统或应用程序升级、恶意软件感染或文件损坏以及用户错误操作等情况发生时&#xff0c;mfc140u.dll文…

C/C++内存管理详解

目录 一、C内存分布 二、C语言与C内存管理方式 1、C语言中动态内存管理方式&#xff1a;malloc/calloc/realloc/free 2、C中的内存管理方式&#xff1a;new/delete 三、operator new与operator delete函数 1、函数概念&#xff1a; 2、函数使用&#xff1a; 3、底层原理…

【机器学习笔记】12 聚类

无监督学习概述 监督学习 在一个典型的监督学习中&#xff0c;训练集有标签&#x1d466; &#xff0c;我们的目标是找到能够区分正样本和负样本的决策边界&#xff0c;需要据此拟合一个假设函数。无监督学习 与此不同的是&#xff0c;在无监督学习中&#xff0c;我们的数据没…

4 月 9 日至 4 月 10 日,Hack.Summit() 2024 首聚香江

Hack.Summit() 是一系列 Web3 开发者大会。2024 年的活动将于 2024 年 4 月 9 日至 4 月 10 日在香港数码港举行。自十年前首次举办以来&#xff0c;此次会议标志着 Hack.Summit() 首次在亚洲举办&#xff0c;香港被选为首次亚洲主办城市&#xff0c;这对 Hack VC 和该地区都具…

BuildAdmin - 免费开源可商用!基于 ThinkPHP8 和 Vue3 等流行技术栈打造的商业级后台管理系统

一款包含 PHP 服务端和 Vue 前端代码的 admin 管理系统&#xff0c;实用性很强&#xff0c;推荐给大家。 BuildAdmin 是一个成熟的后台管理系统&#xff0c;后端服务采用 ThinkPHP8 &#xff0c;数据库使用 Mysql&#xff0c;前端部分则使用当前流行的 Vue3 / TypeScript / Vi…

Netty Review - ByteBuf扩容机制源码解析

文章目录 Pre概述前置知识&#xff1a; 名词解释writeByte 源码解析实现ensureWritable0(minWritableBytes)ensureWritable0alloc().calculateNewCapacity 总结 Pre Netty Review - 直接内存的应用及源码分析 Netty Review - 底层零拷贝源码解析 Netty Review - ByteBuf内存…

python - OSError:错误没有名为 [‘pytorch_model.bin‘

python - OSError&#xff1a;错误没有名为 [‘pytorch_model.bin’] 自己训练的模型存储好了以后 model MT5ForConditionalGeneration.from_pretrained(“ner/best”) 之前还可以跑 现在报错 错误没有名为 [‘pytorch_model.bin’] 还原了一下conda env 把四版变成三版了 …

人工智能学习与实训笔记(十五):Scikit-learn库的基础与使用

人工智能专栏文章汇总&#xff1a;人工智能学习专栏文章汇总-CSDN博客 本篇目录 一、介绍 1. 1 Scikit-learn的发展历程及定义 1.2 理解算法包、算法库及算法框架之间的区别和联系 二、Scikit-learn官网结构 三、安装与设置 3.1 Python环境的安装与配置 3.2 Scikit-lea…

【精选】Java面向对象进阶——接口细节:成员特点和接口的各种关系

&#x1f36c; 博主介绍&#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 hacker-routing &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【应急响应】 【Java】 【VulnHub靶场复现】【面试分析】 &#x1f389;点赞➕评论➕收藏 …

1.逆向基础

文章目录 一、前言二、什么是逆向&#xff1f;三、软件逆向四、逆向分析技术五、文本字符六、Windows系统1.Win API2.WOW643.Windows消息机制4.虚拟内存 一、前言 原文以及后续文章可点击查看&#xff1a;逆向基础 逆向真的是一个很宏大的话题&#xff0c;而且大多数都是相当…

从代码的层面掌握LLM的路线

原则&#xff1a;从易到难&#xff0c;只用 pytorch 从第一个项目来熟悉 transformer 的使用&#xff1b; 从第二个项目来掌握对训练数据的使用方法及 transformer 的 decoder 的细节&#xff1b; 从第三个项目来理解 LLM 的整个过程&#xff1b; 1&#xff0c;Transformer t…

2024/2/17 图论 最短路入门 dijkstra 1

目录 算法思路 Dijkstra求最短路 AcWing 849. Dijkstra求最短路 I - AcWing 850. Dijkstra求最短路 II - AcWing题库 最短路 最短路 - HDU 2544 - Virtual Judge (vjudge.net) 【模板】单源最短路径&#xff08;弱化版&#xff09; P3371 【模板】单源最短路径&#xf…

echarts制作两个柱状图

let colorList[#02ce8b,#ffbe62,#f17373]; let data1 [90,80,70,50] option { title:[{ // 第一个标题text: 环保检测, // 主标题textStyle: { // 主标题样式color: #333,fontWeight: bold,fontSize: 16},left: 20%, // 定位到适合的位置top: 10%, // 定位到适合的位置},{ //…

【plt.scatter绘制散点图】:从入门到精通,只需一篇文章!【Matplotlib】

【plt.scatter绘制散点图】&#xff1a;从入门到精通&#xff0c;只需一篇文章&#xff01;【Matplotlib】&#xff01;&#x1f680; 利用Matplotlib进行数据可视化示例 &#x1f335;文章目录&#x1f335; 一、plt.scatter入门&#xff1a;轻松迈出第一步 &#x1f463;二、…

各类电纸书使用体验

对移动阅读一直有着强烈的愿望&#xff0c;想要一个易于携带&#xff0c;又能看着比较大气的电子阅读器&#xff0c;这是一个矛盾...所以现在用着海信Hi Reader Pro&#xff0c;还想再寻找一个合适的家用阅读器&#xff0c;对自己用过的阅读器总结一下&#xff0c;给大家做个参…

图像卷积、步长、填充、特征图、多通道卷积、权重共享、感受野、池化

图像卷积、步长、填充、特征图、多通道卷积、权重共享、感受野、池化 卷积神经网络的一些基本概念&#xff1a;图像卷积、步长、填充、特征图、多通道卷积、权重共享、感受野、池化 1.图像卷积、步长、填充 图像卷积&#xff1a;卷积核矩阵在一个原始图像矩阵上 “从上往下、…

XUbuntu22.04之apt与snap如何重装软件(二百一十二)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…