2024-09-06



// 安装 Rust 语言
// 打开命令行工具,运行以下命令:
// 如果你已经安装了 rustup,你可以直接安装 Rust 编译器:
rustup-init
 
// 安装成功后,验证安装:
rustc --version
 
// 创建一个新的 Rust 项目
// 在命令行中,导航到你希望创建项目的目录,然后运行:
cargo new hello_world
cd hello_world
 
// 编辑项目源代码
// 打开 `src/main.rs` 文件并替换内容为:
// 文件 `src/main.rs`
fn main() {
    println!("Hello, world!");
}
 
// 运行你的 Rust 程序
// 在项目目录中,运行:
cargo run
 
// 如果你想要构建发布版本的程序,运行:
cargo build --release
 
// 这将在 `target/release/` 目录下生成一个优化过的可执行文件。

这个例子展示了如何安装 Rust 语言,创建一个新的 Rust 项目,编辑和运行一个简单的 "Hello, world!" 程序。这个过程对于学习 Rust 语言和 Cargo 包管理器都是有帮助的。

2024-09-04

要在Linux环境下部署Wiki.js并配置公网地址远程访问,请按照以下步骤操作:

  1. 安装Node.js和MongoDB:



sudo apt update
sudo apt install -y nodejs
sudo apt install -y npm
sudo systemctl start mongodb
sudo systemctl enable mongodb
  1. 确保Node.js和npm的版本满足Wiki.js的要求。
  2. 创建一个新的Wiki.js项目:



npm install -g wiki.js
wiki.js init /path/to/wikijs
cd /path/to/wikijs
npm install
  1. 配置Wiki.js的配置文件config/local.yml,确保数据库连接正确。
  2. 启动Wiki.js服务:



npm start
  1. 配置服务器防火墙允许外部访问。如果你使用的是云服务,通常有一个安全组或防火墙设置,你需要添加规则来允许80(HTTP)或443(HTTPS,如果配置TLS)端口的流量。
  2. 如果你有一个域名,你可以配置一个域名DNS解析到你的服务器公网IP,并在Wiki.js的配置文件中设置HTTPS支持。
  3. 如果你没有域名,你可以使用服务器的公网IP直接访问Wiki.js。

以上步骤提供了一个基本的Wiki.js部署流程。根据你的具体需求和环境配置,可能需要额外的步骤,例如配置反向代理、设置HTTPS等。

2024-09-04

以下是一个简单的todoList清单的实现,使用了HTML、CSS和JavaScript。




<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Todo List</title>
<style>
    #todos {
        width: 300px;
        margin: 0 auto;
    }
    #todos input {
        width: 100%;
        padding: 10px;
        margin-bottom: 10px;
    }
    #todos ul {
        list-style-type: square;
        padding-left: 20px;
    }
</style>
</head>
<body>
 
<div id="todos">
    <input type="text" id="todo-input" placeholder="Add a task">
    <button onclick="addTodo()">Add</button>
    <ul id="todo-list"></ul>
</div>
 
<script>
    function addTodo() {
        var input = document.getElementById('todo-input');
        var todoList = document.getElementById('todo-list');
        if (input.value) {
            var newItem = document.createElement('li');
            newItem.textContent = input.value;
            todoList.appendChild(newItem);
            input.value = '';
        }
    }
</script>
 
</body>
</html>

这个实现包括了一个文本输入框和一个按钮,用户可以在输入框中输入任务,点击按钮后将任务添加到清单中。每个任务是一个列表项(li),它们被添加到无序列表(ul)中。使用JavaScript函数addTodo处理添加任务的逻辑。

2024-09-04



<template>
  <div>
    <p>{{ count }}</p>
    <button @click="increment">增加</button>
  </div>
</template>
 
<script>
import { ref, reactive } from 'vue';
 
export default {
  setup() {
    // 使用ref创建响应式的基本类型数据
    const count = ref(0);
 
    // 使用reactive创建响应式的对象
    const state = reactive({
      message: 'Hello Vue 3!'
    });
 
    // 定义一个方法用于增加count的值
    function increment() {
      count.value++;
    }
 
    // 暴露到模板,返回一个对象,这样模板就可以访问这些变量和函数
    return {
      count,
      state,
      increment
    };
  }
};
</script>

这个简单的Vue 3组件示例展示了如何使用setup函数、ref函数和reactive函数来创建响应式数据和方法。setup函数是Vue 3组件中一个新的组成部分,它在组件实例被创建时执行,允许我们使用Composition API。ref用于基本类型数据,而reactive用于复杂对象类型。通过setup函数返回的对象,我们可以在模板中访问这些响应式数据和方法。

2024-08-27

在JavaScript中,没有内置的直接调用打印功能的API。但是,你可以使用一些技巧来模拟打印功能。

一种方法是使用window.print(),这会打开浏览器的打印预览界面,允许用户直接打印当前页面的内容。




window.print();

如果你想打印页面上特定的部分,你可以创建一个新窗口或iframe,将需要打印的内容写入该窗口或iframe,然后调用print方法。




// 创建一个新的iframe
var printFrame = document.createElement('iframe');
printFrame.style.visibility = 'hidden';
document.body.appendChild(printFrame);
 
// 需要打印的内容
var content = document.getElementById('printSection').innerHTML;
 
// 写入内容到iframe
var frameDocument = printFrame.contentDocument || printFrame.contentWindow.document;
frameDocument.open();
frameDocument.write('<html><head><title>Print</title>');
frameDocument.write('</head><body>');
frameDocument.write(content);
frameDocument.write('</body></html>');
frameDocument.close();
 
// 调用打印功能
printFrame.contentWindow.print();
 
// 清理,移除iframe
document.body.removeChild(printFrame);

请注意,这种方法可能会受到浏览器安全设置和用户的打印设置的影响。

2024-08-27



import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.Spider;
import us.codecraft.webmagic.processor.PageProcessor;
 
public class C919PhotoGather implements PageProcessor {
 
    private Site site = Site.me().setRetryTimes(3).setSleepTime(1000);
 
    @Override
    public Site getSite() {
        return site;
    }
 
    @Override
    public void process(Page page) {
        // 假设页面上有用于下载的图片链接列表,我们通过jQuery选择器提取这些链接
        List<String> imageUrls = page.getHtml().$("div.g-content img").each(new Function<Element, String>() {
            @Override
            public String apply(Element element) {
                return element.attr("data-original");
            }
        });
 
        // 将提取的图片链接保存到页面对象中,供之后处理
        page.putField("imageUrls", imageUrls);
 
        // 提取下一页链接并加入爬虫的爬取队列
        String nextLink = page.getHtml().$("a.next").links().get();
        page.addTargetRequest(nextLink);
    }
 
    public static void main(String[] args) {
        Spider.create(new C919PhotoGather())
                .addUrl("http://photo.c-star.org/C919/")
                .thread(5)
                .run();
    }
}

这个代码实例展示了如何使用XxlCrawler库来实现一个简单的网页爬虫,该爬虫会从一个模拟的商飞C919相册页面开始,提取该页面上的图片链接,并且跟踪分页,爬取整个相册的所有图片。这个例子教会开发者如何使用XxlCrawler进行基本的网页爬取工作。

2024-08-27

字体反爬通常是指网站通过设置自定义字体(Web Fonts)来保护数据,使得爬虫难以从网页中直接解析出文本内容。这里提供一个基本的方法来处理这种情况:

  1. 分析网站的字体文件:网站通常会在其服务器上提供.woff.woff2等格式的字体文件。你需要下载这些字体文件。
  2. 使用fontTools库来转换字体文件:fontTools是Python中处理字体的库。
  3. 使用pyftsubset工具来提取特定字符的子集字体。
  4. 使用ReportLab库来创建一个简单的PDF,并使用提取出的字体。
  5. 使用OCR技术(如tesseract)来识别图片中的文本。

以下是使用fontToolspyftsubset的示例代码:




from fontTools.ttLib import TTFont
import pyftsubset
 
# 下载的字体文件路径
font_path = 'path_to_font.woff'
 
# 加载字体
font = TTFont(font_path)
 
# 提取子集字体
subset_font = pyftsubset.Subset(font_path, options=['--text=0123456789abcdefghijklmnopqrstuvwxyz'])
with open('subset_font.woff', 'wb') as out:
    out.write(subset_font.subset())
 
# 接下来,你可以使用OCR工具来处理网页截图,并尝试识别文本。
# 例如,使用tesseract识别图片中的文本:
# !tesseract subset_font.woff output -l eng --oem 3 --psm 6 nohup

请注意,这个方法可能不总是有效,因为有些网站采用了更高级的防爬策略,例如动态渲染、JavaScript渲染的内容等。此外,这种方法对于处理复杂的布局和样式可能会有挑战。对于复杂的网站,可能需要更高级的图像处理和机器学习技术来解决。

2024-08-27



<template>
  <div>
    <input v-model="publicKey" placeholder="请输入RSA公钥" />
    <button @click="encryptData">加密数据</button>
  </div>
</template>
 
<script>
import JSEncrypt from 'jsencrypt/bin/jsencrypt'
 
export default {
  data() {
    return {
      publicKey: '',
    }
  },
  methods: {
    encryptData() {
      const encrypt = new JSEncrypt()
      encrypt.setPublicKey(this.publicKey)
      const encrypted = encrypt.encrypt('需要加密的数据')
      console.log('加密后的数据:', encrypted)
      // 这里可以将加密后的数据发送到后端
    }
  }
}
</script>

这段代码展示了如何在Vue 3应用中使用jsencrypt库进行数据加密。用户在输入框中输入RSA公钥,点击按钮后,会触发encryptData方法,使用公钥对默认的字符串"需要加密的数据"进行加密,并在控制台输出加密后的结果。在实际应用中,你可以替换默认的数据,并将加密后的数据发送到后端进行处理。

2024-08-27



import 'package:flutter/material.dart';
 
void main() => runApp(MyApp());
 
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomePage(),
    );
  }
}
 
class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('数据卡和数据表'),
      ),
      body: ListView(
        children: <Widget>[
          Card(
            child: Column(
              children: <Widget>[
                ListTile(
                  title: Text('张三'),
                  subtitle: Text('工程师'),
                ),
                ListTile(
                  title: Text('联系方式'),
                  subtitle: Text('电话:1234567890'),
                ),
                ListTile(
                  title: Text('地址'),
                  subtitle: Text('北京市朝阳区'),
                ),
              ],
            ),
          ),
          // 添加更多的Card...
        ],
      ),
    );
  }
}

这段代码创建了一个简单的Flutter应用,其中包含一个HomePage页面,该页面使用ListView来展示多个Card。每个Card包含了一个Column,其中包含了几个ListTile,用于展示不同类型的数据。这是学习Flutter布局和数据展示的一个很好的起点。

2024-08-27

在Vue.js框架中,watchcomputedwatchEffect都用于响应数据的变化执行特定的操作,但它们之间有明显的区别:

  1. computed:是一个依赖于其他响应式属性的属性,它是基于它的依赖进行缓存的,只有当依赖发生变化时,才会重新计算。



// Vue 2.x
computed: {
  fullName: function () {
    return this.firstName + ' ' + this.lastName
  }
}
 
// Vue 3.x
import { computed, ref } from 'vue'
 
const firstName = ref('John')
const lastName = ref('Doe')
const fullName = computed(() => firstName.value + ' ' + lastName.value)
  1. watch:用于观察特定响应式属性的变化,并执行相应的异步操作或者代码块。



// Vue 2.x
watch: {
  firstName: function (val) {
    console.log('First Name changed!', val)
  }
}
 
// Vue 3.x
import { watch, ref } from 'vue'
 
const firstName = ref('John')
 
watch(firstName, (newVal, oldVal) => {
  console.log('First Name changed!', newVal, oldVal)
})
  1. watchEffect:它不依赖于特定的响应式属性,而是当响应式属性发生变化时,它会自动执行一段副作用代码。



// Vue 2.x
watchEffect: function () {
  console.log('Full Name is: ' + this.firstName + ' ' + this.lastName)
}
 
// Vue 3.x
import { watchEffect, ref } from 'vue'
 
const firstName = ref('John')
const lastName = ref('Doe')
 
watchEffect(() => {
  console.log('Full Name is: ' + firstName.value + ' ' + lastName.value)
})

总结:computed是基于依赖进行的计算,watch用于观察响应式属性的变化,而watchEffect则是自动执行无目标的副作用代码。