Web3.0ベースのブロックチェーン画像アップロード

始める前に、まず基本的な概念を簡単に理解しましょう。以下のいくつかの点にまとめました。Web3.0とは何か、ブロックチェーンとどのような関係があるのか?(前回の記事がここで役立ちますね) 要件:PythonベースのWeb 3.0画像アップロードシステムを開発します。このシステムは、ユーザーが画像をアップロードし、その画像を分散型ネットワークに保存し、同時にトランザクション情報をブロックチェーンに記録することを可能にします。もともとは遊びで書いていたもので、ユーザー認証やファイル操作を統合した完全な管理システムにして、「画像アップロードサービスの最終的な解決策」にしようと考えたこともありましたが、実際にやってみるとあまり現実的ではないことに気づき、断念しました。しかし、私は昔から画像にこだわりがあるのです。 ステップの概要 環境設定:Pythonを使用して開発し、必要なPythonライブラリをインストールします。 IPFS統合:画像をIPFSにアップロードし、画像のCID(Content Identifier)を取得します。 ブロックチェーン統合:IPFSのCIDをブロックチェーンに記録します。 Webインターフェース:Flaskを使用して、ユーザーが画像をアップロードできるWebインターフェースを作成します。 詳細なステップ 1. 環境設定 必要なPythonライブラリをインストールします: pip install flask web3 ipfshttpclient 2. IPFS統合 IPFS(InterPlanetary File System)は、ピアツーピアのファイルストレージプロトコルです。ipfshttpclientライブラリを使用してIPFSネットワークと対話できます。 まず、IPFSノードをインストールして実行していることを確認してください。まだIPFSをインストールしていない場合は、IPFS公式サイトでインストールガイドを見つけることができます。 以下は、画像をIPFSにアップロードするコード例です: import ipfshttpclient def upload_to_ipfs(file_path): client = ipfshttpclient.connect('/ip4/127.0.0.1/tcp/5001') res = client.add(file_path) return res['Hash'] 3. ブロックチェーン統合 web3.pyライブラリを使用してIPFSのCIDをブロックチェーンに記録します。ここではイーサリアム(Ethereum)をサンプルブロックチェーンとして使用します。 以下は、IPFSのCIDを保存するための簡単なスマートコントラクトの例です: pragma solidity ^0.8.0; contract IPFSStorage { mapping(address => string[]) public userCIDs; function storeCID(string memory cid) public { userCIDs[msg.sender].push(cid); } function getCIDs() public view returns (string[] memory) { return userCIDs[msg.sender]; } } このコントラクトをコンパイルしてデプロイした後、以下のPythonコードを使用してスマートコントラクトと対話します: ...

2024年6月17日 · 2 分 · MoeJue

ESP8266-NodeMCU開発ボードを使って、私のQQアバターを表示してみる。

ええ、自分でESP8266開発ボードのファームウェアを書くと言っていた私が戻ってきました。20年前に約束した通り、今日、その願いを叶えに戻ってきました。ESP8266串口WiFi模块 - WiFi杀手 今日はOLEDディスプレイも接続します。今回購入したのは4ピンのOLED(128*64)で、カラー表示には対応していません。 NodeMCU開発ボード NodeMCUはオープンソースのIoTハードウェア開発ボードです。WIFI機能をサポートし、Arduino開発ボードと非常に似た使用方法であるため、近年、世界中のメイカーたちからますます人気を集めています。NodeMCUのサイズはArduino Nanoに似ています。Arduinoチームによって開発されたものではありませんが、Arduino IDEを使用して開発することも可能です。 あらゆるものがインターネットに接続されるIoTの基盤として、まずIoT制御ボードのコストが高すぎてはいけません。高価なIoT制御コンポーネントは、プロジェクトのコスト管理に不利であり、多くのメイカー愛好家が学習し使用する上でも不利です。この点において、NodeMCUはRaspberry PiやArduinoファミリーのIoTプラットフォームなどよりも優位性があります。 注意深い方はすでにお気づきかもしれませんが、私の開発ボードはESP8266-NodeMCUと呼ばれています。しかし、他のウェブサイトや資料では、ESP8266と表記されたり、NodeMCUと表記されたりすることがあります。では、ESP8266とNodeMCUの間にはどのような関係があるのでしょうか? ESP8266はチップ(鉄製のケースに収められた四角いもの)であり、NodeMCUはESP8266チップを核とした開発ボードです。下の図に示す通りです。 小さなチップのピンをコンピューターに接続し、プログラムをアップロードするなどの操作を行うのは非常に困難であるため、ESP8266チップを中心とした様々な開発ボードが誕生しました。NodeMCUもこれらの開発ボードの一つです。 NodeMCU開発ボード上の2列のピンヘッダーは、ESP8266チップのピンに接続されています。開発ボード上の2列のピンヘッダーがあれば、デュポン線を使ってチップのピンを実験回路に簡単に接続できます。NodeMCU開発ボードにはUSBポートと電圧変換回路も搭載されています。これらは私たちに大きな利便性を提供します。USBデータケーブル1本で、ESP8266への給電とプログラムのアップロードを簡単に実現できます。もちろん、NodeMCU開発ボードの回路機能はこれだけではありませんが、これ以上は深掘りしません。 ドライバーのインストール 以前にも開発ボードのドライバーインストールについては説明しましたが、十分詳細ではありませんでした。 現在市販されているESP8266ドライバーには様々な種類があり、同じNodeMCU開発ボードであってもドライバーが異なる場合があります。現在主流なのはCH340とCP210Xのドライバーです。 ドライバーのダウンロードは、チップメーカーの公式サイトから直接行ってください。 CP210X:https://cn.silabs.com/developers/usb-to-uart-bridge-vcp-drivers CH340C:https://www.wch.cn/downloads/CH341SER_EXE.html ご自身のプラットフォームに適したドライバーインストーラーをダウンロードしてください。ご自身のシリアルチップのモデルがドライバーのサポート範囲内にあるか、よく確認する必要があります。 自分の開発ボードに必要なドライバーを確認する方法 直接見る。下の図の縦長の黒い長方形がUSB-シリアル変換チップです。その上にチップのモデル名が記載されています。 購入した販売店に尋ねる。 ディスプレイのはんだ付け はんだ付けを間違えないでください。間違えるとチップが焼損します。OLEDの配線: GND - GND VCC - VCC SCL - GPIO5(D1) SDA - GPIO4(D2) はんだごて加熱中 以下がはんだ付け完了したものです。配線に注意してください。この順番であるとは限りません。名称を確認してください。 Arduino IDEのインストール Arduino IDEをダウンロード https://www.arduino.cc/en/software インストール。インストールまで私が教える必要がありますか? 設定。「ツール」-「ボード」-「ボードマネージャー」をクリックし、設定でボードアドレスを記述します:http://arduino.esp8266.com/stable/package_esp8266com_index.json その後、対応するサポートライブラリファイルが自動的にダウンロードされます。この間、ネットワークの安定性を確保する必要があります。 開発ボードを選択: NodeMCU1.0(ESP-12EModule) ポートを選択: コンピューターのデバイスマネージャーで開発ボードのCOMポートを見つけます。 Arduinoコード 時々、私が長々と説明するよりも、直接コードを見せる方が手っ取り早いと感じます。あなたもきっと、私の無駄話を聞くよりも直接コードを見たいと思っているでしょう。私も可能な限りコードにコメントを付けました(Arduinoコードの記述はC/C++言語の規範に従ってください)。 以下の例では、WiFi接続にはライブラリを使用しています。初回接続時には、ESP8266が発信するWiFiに携帯電話で接続し、ネットワーク設定を行う必要があります。画面への書き出しにはライブラリを使用しており、中国語の直接書き出しをサポートしています。 これは、WiFi接続と画面への画像表示の簡単な例です。 #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #include <ESP8266WiFi.h> #include <NTPClient.h> #include <WiFiManager.h> #include <U8g2lib.h> #define SDA 4 // SDA引脚,默认gpio4(D2) #define SCL 5 // SCL引脚,默认gpio5(D1) Adafruit_SSD1306 oled(128, 64, &Wire,-1); //OLED 屏幕实例化 WiFiUDP ntpUDP; NTPClient timeClient(ntpUDP,"pool.ntp.org", 8*3600, 60000); U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /*clock=*/SCL, /*data=*/SDA, /*reset=*/U8X8_PIN_NONE); // 选择显示屏幕 // 只执行一次 void setup() { u8g2.begin(); // 初始化 u8g2.enableUTF8Print(); // UTF8允许 u8g2.setFont(u8g2_font_wqy12_t_gb2312b); //字体大小 u8g2_font_wqy15_t_gb2312b // 初始化屏幕 OLED_Init(); OLED_Showchin(1,13,"正在连接WiFi....",0); WiFiManager wifiManager; wifiManager.autoConnect("ESP8266"); OLED_Showchin(1,27,"WiFi连接成功!",0); OLED_Showchin(1,41,"名称: " + WiFi.SSID(),0); OLED_Showchin(1,55,"IP: " + WiFi.localIP().toString(),1); // 获取时间 timeClient.begin(); u8g2.setFont(u8g2_font_wqy15_t_gb2312b); //字体大小 u8g2_font_wqy15_t_gb2312b OLED_Showchin(1,13,"宁小建",0); OLED_Showchin(1,27,"hhhhhhhhhhhh",0); OLED_Showchin(1,55,"大傻逼哈哈哈",1); timeClient.update(); OLED_Showchin(1,20,"当前北京时间: ",0); OLED_Showchin(1,41,timeClient.getFormattedTime(),1); delay(1000); OLED_img(); } // 重复执行程序 void loop() { // 更新时间 // timeClient.update(); // OLED_Showchin(1,27,"当前北京时间: ",0); // OLED_Showchin(1,41,timeClient.getFormattedTime(),0); } // 打印输出到屏幕(支持中文) void OLED_Showchin(uint8_t x, uint8_t y, String string, uint8_t boot) { u8g2.setCursor(x, y); //设置显示坐标 u8g2.print(string); // 指定缓存区需要打印的字符串 u8g2.sendBuffer(); // 将定位信息发送到缓冲区 if(boot == 1){ delay(1000); u8g2.clearBuffer(); // 清除缓存,其实初始化里有清除,循环时一定要加上 } } // 屏幕初始化 void OLED_Init() { oled.begin(SSD1306_SWITCHCAPVCC, 0x3C); //"SSD1306_SWITCHCAPVCC"表示显示器为OLED ,"0x3C"为OLED屏幕默认通信地址 oled.setTextColor(WHITE);//开像素点发光 oled.clearDisplay();//清屏 } // 输出屏幕 void OLED_ShowString(uint8_t x, uint8_t y, uint8_t font_size, String string) { oled.setTextSize(font_size); //设置字体尺寸 (>=1) oled.setCursor(x, y); //设置显示坐标 oled.println(string); //显示内容 oled.display(); //开启显示 } // 绘画 void OLED_img() { // 图片数据 const unsigned char gImage_1[518] = { 0X00,0X01,0X40,0X00,0X40,0X00, 0X00,0X40,0X00,0X00,0X00,0X3E,0XF0,0X00,0X00,0X80,0X00,0X00,0X00,0X1F,0XE0,0X00, 0X00,0X00,0X00,0X00,0X00,0X06,0XB0,0X00,0X01,0X00,0X00,0X00,0X00,0X03,0XF8,0X00, 0X00,0X00,0X00,0X00,0X00,0X03,0XFC,0X00,0X00,0X00,0X00,0X00,0X00,0X03,0XDC,0X00, 0X04,0X00,0X00,0X00,0X00,0X01,0XC0,0X00,0X0E,0X00,0X00,0X00,0X00,0X00,0X80,0X00, 0X06,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X01,0X00,0X00,0X00,0X10,0X00,0X00,0X00, 0X08,0X00,0X00,0X00,0X0E,0X00,0X00,0X00,0X08,0X00,0X00,0X00,0X8F,0X00,0X00,0X00, 0X00,0X00,0X02,0X02,0X47,0X00,0X00,0X00,0X00,0X00,0X01,0X10,0X63,0X80,0X00,0X00, 0X00,0X00,0X01,0XC9,0X73,0XC0,0X00,0X00,0X00,0X00,0X00,0XE4,0X79,0XE0,0X00,0X00, 0X00,0X02,0X00,0XFA,0XF9,0XE0,0X00,0X00,0X10,0X02,0X00,0X7D,0X8C,0XF0,0X00,0X00, 0X10,0X03,0X01,0X7E,0X90,0XF1,0X80,0X00,0X10,0X01,0X20,0XFD,0X1C,0X7B,0XE0,0X00, 0X00,0X01,0XA0,0X7D,0X03,0X7B,0X20,0X00,0X10,0X01,0XD8,0XFF,0X8B,0X7E,0X30,0X00, 0X00,0X01,0XFC,0X7F,0X83,0XB6,0X10,0X00,0X00,0X00,0XF7,0XFF,0XC7,0XBE,0X10,0X00, 0X00,0X01,0X8F,0XFF,0XE3,0XF6,0X10,0X00,0X01,0X01,0X4F,0XFF,0XFF,0XFF,0X10,0X00, 0X00,0X01,0XCF,0XFF,0XFF,0XDF,0X10,0X00,0X00,0X01,0XC3,0XFF,0XFF,0XDF,0X70,0X00, 0X01,0X03,0XE3,0XFF,0XFF,0XDF,0XE0,0X00,0X04,0X01,0XE7,0XFF,0XFF,0XDF,0XE4,0X00, 0X07,0X00,0XFB,0XFF,0XFF,0XDF,0XC0,0X00,0X07,0X00,0XFB,0XFF,0XFF,0XFE,0X00,0X00, 0X13,0X00,0X7F,0XFF,0XFF,0XFC,0X00,0X00,0X01,0X20,0X3F,0XFF,0XFF,0XFC,0X00,0X00, 0X00,0X00,0X3F,0XFF,0XFF,0XF8,0X00,0X0B,0X00,0X00,0X1F,0XFE,0X0F,0XF8,0X00,0X1F, 0X00,0X00,0X1F,0XF8,0X6F,0XF0,0X00,0XFF,0X00,0X00,0X1F,0XE1,0XFF,0XF0,0X05,0XFF, 0X00,0X00,0X0F,0XF3,0XFF,0XE0,0X03,0XFF,0X00,0X40,0X0F,0XF7,0XFF,0XC0,0X07,0XFF, 0X00,0X00,0X07,0XFF,0XFF,0X80,0X07,0XFF,0X08,0X00,0X07,0XFF,0XFF,0X00,0X0F,0XFF, 0X00,0X00,0X23,0XFF,0XFE,0X00,0X0F,0XFF,0X00,0X08,0X60,0XFF,0XFE,0X00,0X0F,0XFF, 0X00,0X40,0X20,0X3F,0XFE,0X00,0X1F,0XFF,0X00,0X00,0X10,0X0B,0XFF,0X80,0X1F,0XFF, 0X00,0X00,0X40,0X00,0X3F,0X00,0X1F,0XFF,0X00,0X00,0X10,0X00,0X3F,0X00,0X1F,0XFF, 0X20,0X00,0X02,0X00,0X3F,0X00,0X3F,0XFF,0X00,0X00,0X00,0X00,0X7F,0X80,0X3F,0XFF, 0X00,0X00,0X00,0X10,0X7F,0X80,0X7F,0XFF,0X00,0X00,0X00,0X80,0X7F,0X80,0X7F,0XFF, 0X10,0X00,0X00,0X00,0X7F,0X80,0XFF,0XFF,0X30,0X00,0X00,0X00,0X7F,0X80,0XFF,0XFF, 0X10,0X10,0X00,0X00,0X7F,0XC1,0XFF,0XFF,0X00,0X00,0X00,0X00,0X7F,0XF3,0XFF,0XFF, 0X00,0X00,0X01,0X00,0X3F,0XFF,0XFF,0XFF,0X00,0X00,0X00,0X04,0X3F,0XFF,0XFF,0XFF, 0X00,0X00,0X00,0X00,0X3F,0XFF,0XFF,0XFF,0X00,0X00,0X10,0X80,0X1F,0XFF,0XFF,0XFF, 0X01,0X00,0X00,0X05,0X1F,0XFF,0XFF,0XFB,0X00,0X00,0X00,0X00,0X1F,0XF7,0XFF,0XFC, 0X00,0X00,0X00,0X00,0X1F,0XFB,0XFF,0XFF,0X00,0X00,0X40,0X00,0X19,0XFF,0XFF,0XFF, }; oled.clearDisplay(); oled.drawBitmap(3, 1, gImage_1, 64, 64, WHITE); oled.display(); } ...

2024年6月16日 · 4 分 · MoeJue

申し訳ありません、戻ってきました!

それは月明かりもなく、風雨が激しく、何も見えない暗い夜でした。何か起こりそうな予感がしました。 「事故」とパンデミックの影響で、私は一時的に「植物状態」になり、二次元の世界に旅立つ寸前でしたが、幸いにも「救出」されました。この数年間、私を探してくれたメッセージも受け取れていません。まだ私を気にかけてくれている方々に感謝します。ありがとうございます。 悪いのは私ではなく、この運命づけられた世界なのです。 この数年間、私を探してくれた人々や出来事についても、私は全く知りません。QQやWeChatのメッセージも、長期間受け取れていません 何年も更新されていなかった私のアイコンが再び点灯したのを見て、多くの友人がどうしたのかと尋ねてきました。会ったことのないネット上の友人たちに、いや、友人という方が親しい呼び方かもしれませんね、感謝しています。あなたがたが私のことを覚えていてくれたことに、私はとても感動しています。 探し続けてくれたこと、三年 世界中を探してくれた 感動して言葉になりません。以下が本文です。 ブログについて ブログが初めて開設されたのは2016年6月9日です。もうすぐ8年になります。様々な困難の中でも、たくましく生き残ってきました。この間、たくさんの仲間と出会い、一緒に議論し、共に進歩し、共に成長してきました。だから、このブログをここで終わらせたくありません ブログのデータは元々七牛雲に自動バックアップされていましたが、今になって知ったのですが、何らかの理由で19年10月頃にバックアップが停止していました。「インターネットには記憶がある」と言われますが、「頭は断たれても血は流れても、データは失ってはならない」という精神で、数日間、広大なインターネットを探し回り、ついにブログのウェブサイトアーカイブを見つけました。私のブログの過去のバージョンはこちらからご覧いただけます archive (有名なウェブサイトアーカイブプロジェクトです) そこで、記事とコメントのデータをスクレイピングするPythonスクリプトを作成しました。スクレイピングした後、すでに誰かがバックアップしてくれていることに気づきました(私のブログは以前3年間、誰かにスポンサーしてもらっていました)。 ブログの移転 ブログを博客園に移転したのは、やむを得ない選択でした。 ブログの元のドメイン(52ecy.cn, moeins.cn, moeins.com)が期限切れ後に他人に取得されてしまい、交渉しても取り戻すことができませんでした。やむを得ず、一時的に博客園にブログを移転することにしました(将来的に自分で構築するかどうかは検討中です)。また、現在では自分のシステムをいじる時間がそれほどなく、博客園に置く方がより手間がかからず楽かもしれません。しかし、コメントはそれほど便利ではなく、投稿するにはログインが必要です。もちろん、何か問題があればグループで私にメンションしてください。 実は、18年末にはすでにテーマを変更したいと考えていました -> 今度こそ本当に延期します (私は本当に遅延癖があります、自分に感心します)。しかし、以前のemlogシステムには適切な既成テーマがなく、自分で移植するのが面倒だったので、ずっと延期していました。 以前のテーマは、見た目が良くなく、個性に欠け、ただ真面目なだけで、私の個性やスタイルに合わないと思っていたので、ずっと変えたいと思っていました。しかし、私の美的センスは素晴らしいのですが、私の美意識に合ったテーマを自分で一から書くとなると、少し難しいのです。 その後、博客園ユーザーの不忘编码さんのブログを偶然見て、博客園でもこのように自分で美化できることを知りました。「私のブログも失われたり、アクセスできなくなったりするのは嫌だ」という思いから、一時的に博客園に移行することを決めました。 ずっとこのような二次元風のテーマに変えたかったのです。現在、このブログの美化スタイルは、桜荘のペットな彼女のWordPressテーマSakuraをベースに、不忘编码さんが移植したものですが、バグや細部の問題が多く、さらに2日間かけて最適化しましたが、まだ多くのページが最適化されていません。後でゆっくりと進めていきます。(明日できることを、なぜ明日の自分に残しておかないのか?) 以前のemlogブログではHTMLのTinyMCEエディタ、しかも古いバージョンを使用していたため、生成される記事のHTMLコードは非常に混乱していました。そのため、博客園のmarkdown形式に移行した際に、多くのスタイル互換性の問題が発生しました。できる限り修正しましたが、すべての記事が正常に表示されることを保証することはできません。見つけたら、ゆっくりと修正していきます。 博客園は、自作ブログシステムのワンクリック移行機能をサポートしていないため、記事の公開時間やコメント情報を一緒に移行することはできませんでした。しかし、元の状態をそのまま残したいと思ったので、この記事にすべて書き込みました。プライベートコメントも非表示のままです。(自作ブログシステムの件は博客園チームともコミュニケーションを取りましたが、後期の開発で追加するとのことでした。彼らを困らせるつもりはありません。彼らも経営が苦しいようです。記事の公開にはCnblogのVScodeプラグインを使用しました。) 友情リンクも個別のページとして移行しましたが、多くのリンク先のウェブサイトがアクセスできなくなったり、すでにリンクを削除したりしていました。今は独立したドメインを持っていないので、友情リンクを申請するのも申し訳ない気持ちになります…。 以前のブログの画像はすべて新浪に保存されていましたが、いつか失われるのではないかと心配していました。そのため、普段は七牛雲と新浪の両方に保存していましたが、今ではすべて博客園に移行しました。 なぜブログを書くのか? これらのことがそんなに重要なのかと思う人もいるかもしれません。時々、何かを言いたい、何かを書きたいと思うのですが、誰も話を聞いてくれず、書く場所もなく、ただそのような場所が必要なのです。ブログをやっているのは、トラフィックやお金のためではなく、自分の小さな世界を作り、自分の小さなコミュニティで気ままに過ごしたいだけなのです。おそらく、この情熱があるからこそ、私はゆっくりと続けることができたのでしょう。しかし、事態は思い通りにはいかず、事故が起こってしまいました。 以前のブログ仲間の多くは、姿を消したか、更新をやめてしまいました。本当に残念です。彼らと知り合う前にそうなってしまいました。(特に月宅というやつ) @寒穹 というやつは私にこう言いました。「阿珏、ずいぶん経つのに、どうしてまだそんなに二次元なんだ?」 長年変わらないのは、私自身なのかもしれません。 まだ私を覚えていてくれて、私に良くしてくれる人がたくさんいることに、とても嬉しく、そして感謝しています。 こんなにたくさんの画像を投稿すべきではなかったかもしれません。失われたブログを偲んで、私の127(おそらくPCのストレージを指している)の中で永遠に生き続けます。 Pythonコード 移行に使用したPythonコードです。あまり役に立たないかもしれませんが、記録として、必要とする人の学習のために残しておきます。 コードを表示 ``` import os import re import time import requests from bs4 import BeautifulSoup from urllib.parse import urlparse, parse_qs # ファイルパスを指定 file_path = “C:\\Users\\Administrator\\Desktop\\blog\\content.txt” save_folder = “C:\\Users\\Administrator\\Desktop\\blog\\content\\” def save_to_file(data, file_name): try: file_path = os.path.join(save_folder, file_name + “.txt”) with open(file_path, ‘a’, encoding=‘utf-8’) as file: file.write(data) print(“データは正常にファイルに保存されました:”, file_path) except Exception as e: print(“ファイルの保存中にエラーが発生しました:”, e) def remove_html_tags(text): soup = BeautifulSoup(text, ‘html.parser’) return soup.get_text() def comment(html_content): comment_matches = re.findall(r’[\s\S]*?<img .*?inal=".*?202.*?/([^"]+)"/>[\s\S]*?<div ’ + ‘class=“comment-content”>(.*?)[\s\S]*?itle=".*?">(.*?)[\s\S]*?(.*?)’, html_content, re.DOTALL) article_comments = ’’ if comment_matches: i = 0 for comment_match in comment_matches: if ‘comment-children’ in comment_match[0]: i += 1 is_reply_comment = ‘>’ * i else: is_reply_comment = ‘>’ i = 1 # アバター サイズは40に制御 # gravatarアバターに対応 https://secure.gravatar.com/avatar/ if ‘gravatar.com’ in comment_match[1]: avatar_url = ‘![](’ + str(re.sub(r’(\?|&)s=\d+’, ‘\\1s=40’, str(comment_match[1]))) + ‘) ’ else: parsed_url = urlparse(comment_match[1]) query_params = parse_qs(parsed_url.query) dst_uin = query_params.get(‘dst_uin’, [‘1638211921’]) avatar_url = ‘![](’+‘https://q1.qlogo.cn/g?b=qq&nk='+str(dst_uin[0])+’&s=40’+’) ’ comment_content = comment_match[2].strip() nickname = comment_match[3].strip() comment_time = comment_match[4].strip() link_url = re.search(r'030.*?/(.*?)" .*? rel’, nickname) # コメントのmarkdown形式を構築 comment_content = is_reply_comment + comment_content.replace(’\n’, ‘>’) comment_content = comment_content.replace(’##このコメントはプライベートコメントです##’, ‘[#このコメントはプライベートコメントです#]’) # 絵文字画像を置換 soup = BeautifulSoup(comment_content, ‘html.parser’) for img in soup.find_all(‘img’): title_text = img.get(’title’, ‘’) img.replace_with(’[#’+title_text+’]’) comment_content = soup.get_text() # コメント投稿者のURLを保存 if link_url: nickname = ‘[’+remove_html_tags(nickname)+’]’ link_url = ‘(’ + link_url[1] + ‘) ’ else: link_url = ’’ nickname = remove_html_tags(nickname) + ’ ’ if i == 1: article_comments += ‘\n’ article_comments += is_reply_comment + avatar_url + nickname + link_url + comment_time + ‘\n’ + comment_content + ‘\n’ return article_comments else: return ’’ def process_article(url): print(“現在実行中===="+url) response = requests.get(url) if response.status_code == 200: html_content = response.text soup = BeautifulSoup(html_content, ‘html.parser’) article_title = soup.find(‘h1’, class_=‘article-title’) article_mate = soup.find(‘div’, class_=‘article-meta’) article_article = soup.find(‘article’, class_=‘article-content’) soup_content = BeautifulSoup(article_article.prettify(), ‘html.parser’) img_tags = soup_content.find_all(‘img’) pattern = r"https://web.*?_/” for img_tag in img_tags: if ‘data-original’ in img_tag.attrs: original_url = img_tag[‘data-original’] else: original_url = img_tag[‘src’] cleaned_url = re.sub(pattern, ‘’, original_url) new_url = ‘https://image.baidu.com/search/down?url=' + cleaned_url img_tag[‘src’] = new_url del img_tag[‘data-original’] article_comment = soup.find(‘div’, class_=‘article_comment_list’) data = “###### `このメッセージが表示されている場合、現在の記事は元のemlogブログシステムから移行されたものです。記事の公開時期が古すぎるため、構成や内容が完全でない場合があります。ご了承ください。`\n\n” + ‘###’ + article_title.text.strip()+’\n\n’+article_mate.text.strip().replace(’\n’, ‘’).replace(’\r’, ‘’).replace(’\t’, ‘’)+’\n’ + soup_content.prettify().replace(’’, ‘’).replace(’’, ‘’) save_to_file(data + ‘\n网友评论:\n\n’, article_title.text.strip()) data = comment(html_content) if not data: return save_to_file(data, article_title.text.strip()) if article_comment: comment_links = re.findall(r’<a\s+href="(.*?)nts"’, str(article_comment)) if comment_links: print(‘ページネーションコメントデータがあります’) for link in comment_links: url = link +“nts” print(url) response = requests.get(url) if response.status_code == 200: html_content = response.text data = comment(html_content) if not data: return save_to_file(data, article_title.text.strip()) print(“ページネーションコメントデータを書き込んでいます”) else: print(“Failed to retrieve the webpage.”) def main(): with open(file_path, ‘r’, encoding=‘utf-8’) as file: for line in file: segments = line.strip().split("—-") if len(segments) > 0: url = segments[0] process_article(url) else: print(“行にURLが見つかりませんでした。”) print(‘次の記事を開始します’) time.sleep(4) if __name__ == “__main__”: main() ```

2024年6月16日 · 3 分 · MoeJue

2020年末のまとめ

年末の総括を書くべきかどうか、何を書くべきか、ずっと悩んでいた。 数日前、楊潔さんがゲームをしていて、“年末のまとめは書いたの?“と聞いてきた。 これがきっかけで、書かなければならないと決心した。 昨年の2020年は、流行り病のせいで、一年があっという間に過ぎてしまい、書き始める前にすべてが終わってしまったような気がした! また、まとめるべきことがあまりないような気がして、何から始めたらいいのかわからなかった。 18年の年末のまとめはこちら→お金持ちになれると思ったけど、なれなかった。 今年は例年のような素晴らしいコピーライティングができなかった。 記事アーカイブ 2020年から月刊ブロガーになりますが、変わらないのは毎日チェックしていることです。 ブログ ブログがオープンボックスブログとして息を吹き返し、私がオープンボックスUPマスターになった年のような気がするが、実際にはオープンボックスは2018年まで遡ることができ、それはすでにあった。つまり、私は2年前からオープンボックスをしていたことになる 他のタイプの記事もたくさん書いてきたとはいえ、1年間NEWで、まだ自分のためのモノをNEWにできていないのは、ちょっと空しい気がする! 人生 流行り病で仕事が滞り、あと数ヶ月は家にいることになったのも、虚しさを感じた理由の一つかもしれない。 後半は、もう意味のない残業はしたくないと、自分をほめて会社を辞めた。 2ヶ月間部屋を借り、2ヶ月間テイクアウトを食べ、2ヶ月間運転を習い、運転免許を取得して広東を離れた。 (この段落は波乱万丈の調子で読んでください) 2021 ここ数カ月、パスポートを取得するために入国管理局に行ったが、やはり流行のせいで、うまくいかなかった。 2021年は流行が緩和されて、パスポートを取得できるようになるといいな。 来年か再来年には海外に行こうと思っている。なぜかと聞かれたことがあるが、私の答えは “いつもの電車の旅とは逆で、見たことのない景色を見るため “だ。 人生の瞬間を記録し、旅にプレイバックを加えるためにGoProを手に入れる! 2020年は少し空虚な一年で、あまり何もできなかったけれど、新しい年は夢に向かって前進し、まだ始めていないことを少しずつ終わらせていこうと思う!

2021年1月26日 · 1 分 · MoeJue

メリークリスマス 礼物

メリークリスマス メリークリスマス 私のクリスマスプレゼントです あっという間に2020年末を迎え、今年のハードウェアメーカーの相次ぐ勢力は、かつてのIntelの費用対効果戦争がIntel第10世代デスクトップクラスプロセッサの価格を上げないボリュームをリリースした後、Nvidia RTX3070が独自のコンシューマーグレードのフラッグシップグラフィックスカードの最後の世代を襲撃し、活気がないと良いことが言え、ハードウェアの性能の可能性を再生するために、優れたマザーボードも当然不可欠である。Asus TUF GAMINGゲーミングエージェントマザーボードは、しっかりとした素材、スタイリッシュなデザイン、手頃な価格で人気があり、今年、ミドルレンジ市場に位置づけられるようにリリースされたばかりのHeavy Gunnerシリーズは、より堅牢な電源構成、2.5G有線NIC、強化された装甲など、フラッグシップ製品から発展した新機能を誇りながら、価格は他のミドルレンジ製品と同じで、当然DIY愛好家の間で人気がある。DIY愛好家の間では当然人気のシリーズだ。 。 ステッカー …… TUOの後継機であるヘビーガンナーを継承したヘビーガンナーシリーズ。 ヘビーガンナーシリーズは、TUF GAMINGシリーズ本来のタフガイスタイルを継承し、ブラックとグリーンを基調としたボディに、TUF GAMING特殊部隊の通常スタイルであるイエローカラーのロゴをあしらい、高い認知度を誇ります。 マザーボードの外観は、大きな冷却アーマーにTUF GAMINGのロゴがプリントされ、ゲーミングの雰囲気が満載です。 TUF GAMINGロゴは大型のクーリングアーマーにプリントされています。 新しいLAG1200インターフェイスは第10世代以前のプロセッサーには対応していないが、それ以降の第11世代には対応しているようだ。 。 メモリスロットに関しては、ASUS TUF GAMING B460M-PRO Heavy Gunnerマザーボードは4つのDDR4メモリスロットを提供し、最大2933MHzの周波数で、ASUS独自のOptiMemメモリ最適化技術を搭載し、メモリのオーバークロック空間と安定性を大幅に向上させることができます。最大128GBのメモリをサポートする。ASUSはまた、このマザーボードの1 3と2 4の位置を異なる色でマークし、2本のRAMスティックを使用する際にメモリを挿入するようユーザーに促している。 MATXバージョンでは、ASUSは128GBメモリに対応しています。 MATX バージョンでは、ASUS TUF GAMING B460M-PRO Heavy Gunner マザーボードは、発熱がより深刻な電源とチップセットのサーマルアーマーに多数のつや消し表面処理を採用しています。このデザインは、マザーボードの熱を素早く奪うだけでなく、マザーボードに非常に強い洗練されたデザインとセンスをもたらします。 。 グラフィックスカードスロットに関しては、マザーボードは2つのPCIeロングスロットを提供します。そのうち1つは、グラフィックスカードの抜き差しによる偶発的な損傷を防ぐために金属製の装甲が装備されており、このスロットはX16モードなので、グラフィックスカードを1枚しか使用しないユーザーは、このスロットにグラフィックスカードを接続することをお勧めします。 マザーボードのI/Oも非常に簡単です。 ASUS TUF GAMING B460M-PROマザーボードのI/Oバッフルはマザーボードに統合されており、マザーボードを取り付ける際のバックプレーンの取り付けステップを減らし、マザーボードの一体感がより強くなっています。統合されたI/Oバッフルのデザインは、以前のASUSハイエンドマザーボードでしか見ることができませんでしたが、現在ではB460チップセットマザーボードにも配置され、取り付け漏れを防ぎ、またホコリや汚れの落下を防ぎます。このマザーボードは2つのUSB 2.0ポートを提供します。 このマザーボードは、2つのUSB 2.0ポート、4つのUSB 3.1Gen1ポート、HDMIポート、DPポートに加え、2.5Gbネットワークポートと5つの通常のオーディオポートを提供します。 があります。 SATAポートは3つ並んで6つあり、2つ目のスロットセットは水平に配置されているため、大型グラフィックスカードが長すぎてポートを塞いでしまうことはありません。 大型グラフィックスカードがポートを塞がないように、2番目のスロットは水平に配置されている。 最後に、オーディオに関して、このマザーボードは、出力108dB SNR、SNR103dBのRealtek S1200A高品質オーディオチップを使用しており、利用可能なサウンドカードチップの中でトップクラスとなっています。 箱の裏側のプレビュー ボックス裏面のプレビュー。 i5-10600kfの中国製ボックスには3年間の全国保証がついており、「K」という接尾辞がついているため、このCPUにはクーラーが付属しておらず、自分で購入する必要があることも側面からわかります。 。

2020年12月25日 · 1 分 · MoeJue

ネット回線速度の速遅による違い

ネット速度の速遅による違いについて ネットワークの普及に伴い、ユーザーは応答速度の速遅をますます重視するようになっています。ウェブサイトが速ければ速いほど、ユーザーの定着率とコンバージョン率も高まります。 簡単に言えば、スピードアップが重要です!ウェブサイトの速度に影響を与える要因はたくさんあります。例えば…………………. 真面目な話は私のスタイルではありません。さて、私のパフォーマンスをご覧ください。 アイデアの起源: 最初は純粋なCSSで実装することを考えました。背景画像をbase64エンコードしてbackground-imageに直接配置すれば、背景画像がウェブページと一緒に読み込まれる効果が得られるだろうと。 ステップ1: まず、事前に準備した素材画像を処理し、水着と水着のスカートを脱がせます ステップ2: 新しいHTMLファイルを作成します ステップ3: 完了。。 すると問題が見つかりました。私の背景画像ファイルサイズが12MBに達していたため、エンコード後の文字列が大きすぎ、ウェブページの読み込みが重く遅くなり、まったくユーザー体験がありませんでした。 さらに、この方法で読み込まれた背景画像は突然表示され、唐突すぎて効果が良くありませんでした。 その後、変更しました: CSS+JavaScriptで実装することにしました。background-imageで背景画像を直接読み込むことで、徐々に表示される効果が得られ、背景画像の読み込みが完了した後、JSで動的に画像を挿入します。 window.onload = function(){ var img=new Image(); img.src=‘裸体.jpg’; if(img.width==0){ alert(‘图片加载失败’) }else{ document.getElementById(“泳衣”).style.backgroundImage=“url(泳衣.png)”; document.getElementById(“泳裙”).style.backgroundImage=“url(泳裙.png)”; } } 思わず一言漏らしました。「なんてひどいネットワークだ、遅すぎて人物画像の服すら読み込めないなんて!」

2020年11月7日 · 1 分 · MoeJue

今日はお祝いしましたか?

一は二を生み、二は四を生み、コードは万物を生み出す……プログラマーたちが創造した世界は、人類により多くの可能性をもたらしました。 年に一度の1024プログラマーの日がまたやってきました。毎年この時期はどんなに忙しくても、時間通りに記事を一本投稿するようにしています。 今年はオープンソースプロジェクトは特に書きませんでしたが、それでもたくさんのコードを書きました。繋ぎ合わせれば地球を二周できるほどです。 2020-1024=996?? 昨年、大きな話題となった996ですが、これはまさか、運命づけられていたのでしょうか。 今年は皆さんと分かち合えるような良いネタがあまりないようです。。 それなら、ACG指向プログラミングと行きましょう~~! 過去の記事も見てみましょう 2019年 1024プログラマーの日、最高のコーディングで、一番クールなエンジニアになろう 2018年 1024プログラマーの日おめでとう 2017年 1024プログラマーの日おめでとう 2016年 プログラマーの祭典1024!今日はお祝いしましたか〜 これはつまり、私のブログが5年間も私に寄り添ってくれたということです。この道のりを共に歩んでくれたあなたと私に感謝します!

2020年10月24日 · 1 分 · MoeJue

真の現実逃避

ずっとVR機器が欲しいという願いがあったのですが、今日ついに叶いました。 @本群吉祥物 のおすすめで、OculusブランドのVR一体型ヘッドセットを購入しました。 カードを開設して節約カードを入手 -> クーポンを取得 -> チャージ -> 注文 -> 一気に完了(心が痛む) Oculusブランドが中国市場に参入していないなどの理由で、ギガビットルーターもセットで購入しました。 届いたのは大きな箱が2つでした 1つはVR本体が入っていて、販売店からUSB充電バッテリーが追加でプレゼントされていました。SMARTOOOLSというスペインブランドで、なかなか良さそうです もう1つの箱には、ギガビットルーターと数百元もするUSB3.0リンクケーブルが入っていました。 ピーナッツの殻のような形をしたルーターです。 読めない説明書がたくさん、しかも外付けファン付き(#泣き笑い)。このルーターブランドも海外製なので、3ピンのプラグはヨーロッパ規格で、国内の3穴コンセントには変換アダプターが必要です。 外箱 - 裏面、下には人気ゲームのおすすめがいくつか載っています。 正面、シンプルでクールです。 パッケージの中の箱には、Oculusのロゴが印刷されています。 蓋を開けると、わぁ! Oculus Quest 6DoF VR、現在市場で最も強力なVR一体型ヘッドセットです。 公式にはコントローラー用の電池が1組、デバイスの基本的な操作説明書、そして分厚くて詳細すぎて読めない説明書が付属しています。 ポーズを決めて撮影、本体+左右コントローラー。 さて、電源を入れて使い始め、ずっと楽しみにしていたBeat Saber、VRChatなどをダウンロードして……現実逃避の旅を始めます……。 後日談: 普段、開封レビューはしません。なぜなら、専門的なレビューには専門的な学術知識が必要で、すごい専門用語を使いこなす必要もあるからです。しかし、私にはそれができませんし、私の記事を読んだ人を、真面目な顔をしてデタラメを言うことで誤解させたくもありません。私はただ、言いたいことを言っているだけです。 VRChatで皆さんをお待ちしています。後で時間があれば、私が遊んでいる動画をBilibiliにもアップロードします。 もしOculus Questについてさらに詳しく知りたい方がいれば、専門的なレビュー動画をおすすめします。 Oculus Quest VRは私たちを「ソードアート・オンライン」「レディ・プレイヤー1」からどれだけ近づけるのか? https://www.youtube.com/watch?v=2z-QyogFp9o (もし開けるなら)

2020年9月18日 · 1 分 · MoeJue

「ジャンカー」が来た

CEOに就任し、才色兼備の女性と結婚、人生の頂点へ。 その第一歩は、まずサーバーを買うことから。 グラフィックボード搭載のサーバー マザーボード メモリ CPUファン ハードディスク + CPU その後、電源ケーブル、LANケーブル、電力計などの細かい部品が続々と届きました。 部品がだいたい揃ったところで、組み立てて電源を入れます。 キーボード、モニター、OSインストール用のUSBメモリはすべて借り物で、起動したらすぐに返却です。 起動プロセスは決して順調ではなく、正常に起動して稼働するまで2、3週間かかりました。 停電でシャットダウンした後、復旧しても誰も起動できない事態に備え、Wi-Fi経由で遠隔起動できるモジュールを購入。これで通電時に自動で起動します。 その後、停電対策として新品のUPS(無停電電源装置)を直接購入しました。停電時のデータ保護、継続的な電力供給、電圧の安定化で、サーバーを守ります。 その後、スペックが追いつかなくなったため、新しいCPUを導入しました。 そして新しいグラフィックボードも。 新しいマザーボード。 最後に、特製のケースに収めます。 これが、皆さんが使っている数千万件クラスのデータを処理するサーバーかもしれません(笑) 現在、サーバーは数ヶ月間、問題なく連続稼働しています。

2020年8月18日 · 1 分 · MoeJue

2020端午節団体旅行

やっとブログを投稿する時間が出来ました。 この端午節は無駄ではなかった。私たちのチームは恵州市双岳湾へ2泊3日の楽しい旅行に行ってきました。 険しい道のりの概要は説明しません…. 双岳湾展望台 早朝にホテルが提供する朝食を済ませた後、双岳湾全体を一望できる展望台へ向かいました。 黄色い小さな車に乗って、渋滞の中をスイスイと歩いて、すぐに山の麓に到着しました。亀の博物館は人が多くてマスクをしていなかったので、このアトラクションはパスしてそのまま山に登りました。 数時間の登山を経て、ついに山の頂上に到着しました 向かい合う二つの三日月のように 山のふもとの景色は美しいでしょう?メイ、なぜここでそんなに時間を費やすのですか? 小興山でのシュノーケリングは、ボートをレンタルして一緒に海に出て、道具を持って海に飛び込みます。 ……救命胴衣を着て、救命浮輪をつけて、監視員にしがみついていると、とても潜れない……ががぁぁぁぁぁぁぁぁぁぁぁぁ 遠い海の島々の近くの水は確かに海岸よりもはるかに透明です 側面の岩礁は岩と呼ばれることもあります。 『軽声少女』の秋山澪を思い出します。よく見ると怖い…ああ…ああ 日没時に戻り、海に沈む夕日を楽しみます は時々海水を一口飲みます、うわー、しょっぱい、バーバーバーバー 水滴が脈打っている 夜はアワビとロブスターを提供 まるで財布から血が出る音が聞こえるかのように、私たちはそれを「アワビ・ロブスター局」と呼んでいます。 ふと夜景の写真を撮り忘れたことに気づいたら終わってました…。 注意! ! ! !次の旅行を楽しみにしています

2020年7月5日 · 1 分 · MoeJue