XML Parser (ESP32/Arduino)
2023.09.01
YouTube でも紹介しています。画像をクリックすると再生できます。
RSS(Rich Site Summary)はXMLで記述され、ニュースやブログなどのヘッドライン情報(タイトルや概要など)を配信するための文書フォーマットの総称です。
それらの更新情報を配信するためのテキストデータは、RSS feed と呼ばれます。
ここで、
RSS一覧 - Yahoo!ニュース
をみてみます。

トピックス内「国内」リンク先
https://news.yahoo.co.jp/rss/topics/domestic.xml
のXML形式ファイルは下記のような構文になってます。
domestic.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<rss version="2.0">
<channel>
<language>ja</language>
<copyright>© Yahoo Japan</copyright>
<pubDate>Thu, 31 Aug 2023 04:12:54 GMT</pubDate>
<title>Yahoo!ニュース・トピックス - 国内</title>
<link>https://news.yahoo.co.jp/topics/domestic?source=rss</link>
<description>Yahoo! JAPANのニュース・トピックスで取り上げている最新の見出しを提供しています。</description>
<item>
<title>岸田首相 北発射「容認できない」</title>
<link>https://news.yahoo.co.jp/pickup/6473916?source=rss</link>
<pubDate>Thu, 31 Aug 2023 02:25:06 GMT</pubDate>
<comments>https://news.yahoo.co.jp/articles/6a1d41b85a08e95f58e0b032834d66df07b801ae/comments</comments>
</item>
<item>
<title>概算要求114兆円程度 過去最大に</title>
<link>https://news.yahoo.co.jp/pickup/6473904?source=rss</link>
<pubDate>Thu, 31 Aug 2023 00:22:10 GMT</pubDate>
<comments>https://news.yahoo.co.jp/articles/827e6eddd96695056e00ab75c7509100ad61b39e/comments</comments>
</item>
<item>
<title>コロナ高額薬、一部自己負担へ</title>
<link>https://news.yahoo.co.jp/pickup/6473900?source=rss</link>
<pubDate>Wed, 30 Aug 2023 23:57:50 GMT</pubDate>
<comments>https://news.yahoo.co.jp/articles/9b1d4dffabcdd8396b4d8a7d4e5d19b6ac931504/comments</comments>
</item>
<item>
<title>関東大震災から6年後 東京の様子</title>
<link>https://news.yahoo.co.jp/pickup/6473925?source=rss</link>
<pubDate>Thu, 31 Aug 2023 03:24:43 GMT</pubDate>
</item>
<item>
<title>台風が沖縄接近 西日本は大雨恐れ</title>
<link>https://news.yahoo.co.jp/pickup/6473896?source=rss</link>
<pubDate>Wed, 30 Aug 2023 23:02:24 GMT</pubDate>
<comments>https://news.yahoo.co.jp/articles/cc13b07e0f831896fa4e5297fe4065eaf27f6cab/comments</comments>
</item>
<item>
<title>最高検 供述誘導疑惑で検事聴取へ</title>
<link>https://news.yahoo.co.jp/pickup/6473895?source=rss</link>
<pubDate>Wed, 30 Aug 2023 22:55:50 GMT</pubDate>
<comments>https://news.yahoo.co.jp/articles/e39755ec949dba00d9e065ec8071ad7a673cf077/comments</comments>
</item>
<item>
<title>王座戦始まる 藤井竜王が八冠挑む</title>
<link>https://news.yahoo.co.jp/pickup/6473912?source=rss</link>
<pubDate>Thu, 31 Aug 2023 01:27:33 GMT</pubDate>
<comments>https://news.yahoo.co.jp/articles/900e08b5363a775b109b2bccfb59f2a93508b437/comments</comments>
</item>
<item>
<title>三浦雄一郎さん90歳 富士山頂到達</title>
<link>https://news.yahoo.co.jp/pickup/6473899?source=rss</link>
<pubDate>Wed, 30 Aug 2023 23:19:01 GMT</pubDate>
<comments>https://news.yahoo.co.jp/articles/dec60f4b0f69d9f4634b71cf6f8f4e46151b7e81/comments</comments>
</item>
</channel>
</rss>
このXML構文を解析して、任意のXMLタグの内容を抽出するツールがXML Parser です。
上記の RSS feed は、Chromeブラウザの機能を使えば容易に取得できますが、このRSS feed のURLはhttpsによるSSL暗号化通信です。
Arduino言語によりfeedをダウンロードするには認証情報が必要なので、まずは証明書を取得しましょう。
今回は、Yahoo!ニュース の認証情報を取得します。

サイトURLの左側の鍵マークをクリック、セレクトボックスから「この接続は保護されています」を選びます。

「証明書は有効です」をクリックします。

証明書ビューア内の「詳細(D)」タブをクリック、「エクスポート」ボタンを押します。
このビューア内の「証明書」→「有効期限」→「終了時刻」で証明書の有効期限を確認できます。

ファイルの種類(T)で、「Base64エンコードASCII形式の証明書チェーン(*.pem;*.crt)」を選択します。
edge01.yahoo.co.jp.crt

この証明書チェーンの各ブロックは下記のように構成されています。
認証には3番目ブロックのroot証明書を使います。
—–BEGIN CERTIFICATE—–
発行されたサーバー証明書ファイルの記述内容
—–END CERTIFICATE—–
—–BEGIN CERTIFICATE—–
中間証明書ファイルの記述内容
—–END CERTIFICATE—–
—–BEGIN CERTIFICATE—–
root 証明書ファイルの記述内容
—–END CERTIFICATE—–
1番下のブロック、root証明書を使用します(後述)。
SSLサーバ証明書のインストールに必要な .PEMファイルを作る
●Adafruit QT Py ESP32-S2 WiFi Dev Board with STEMMA QT
・ESP32-S2 240MHz
・4 MB Flash & 2 MB PSRAM
・2.4 GHz Wi-Fi (SoC)
・Two I2C ports
・Hardware UART
・Hardware SPI
・Hardware I2S on any pins
・3.3V regulator with 600mA peak output
Adafruit QT Py ESP32-S2
●Qt Py ESP32-S2 Pinout
右側に写っているのが、Raspberry Pi Zero 2 W + 拡張ボード、Qt Py ESP32-S2 です。
Raspberry Pi はノートパソコンから Telnet で操作しています。
●プログラム概要
ニュースサイトからRSS feed を取得し、ヘッドライン情報(タイトルとリンク)を抽出します。
ソースコードのビルドには、PlatformIOを使用しています。
Arduino開発環境構築 PlatformIO
XML構文解析ライブラリには、NunniMCAXを使用しました。

NunniMCAX
解凍してソースディレクトリに配置します。
NunniMCAX を使ったサンプルコードが掲載されているサイトです。

ArduinoでXMLを解析する
ESP32 での https の使い方を解説しているサイトです。

ESP32からWiFiClientSecureをつかってHTTPS GETをする方法をちょっと理解した
$ mkdir -p ~/XMLParser
$ cd ~/XMLParser
$ pio init -b adafruit_qtpy_esp32s2
$ vi src/datalink.h
#define SECRET_SSID "xxxxxxxxxxxx"
#define SECRET_PASS "xxxxxxxxxxxxx"
const char* yahoo_co_jp_crt = \
"-----BEGIN CERTIFICATE-----\n" \
"MIIDdzCCAl+gAwBADANBgkqhkiG9w0BAQsFADBdMQswCQQGEwJKUDEl" \
"MCMGA1UEChMcU0gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjUGA1UECxMe" \
"U2VjdXJpdHkgQ2uaWNhdGlvbiBSb290Q0EyMB4XDTA5MDA1MDAzOVoX" \
~~~~~~~~~
"t/2jioSgrGK+PBqAbubKVY8/gA3zyNs8U6qtnRGEmyV7JqR50S+kDFy" \
"1UkC9gLl9B/ran/7Ir5mUf/NVoCqgTLiluHcSmRvaS9mvVXIwAHIRc/" \
"SjnRBUkLp7Y3KozXoEofKd9J+sAro03" \
"-----END CERTIFICATE-----";
複数行の root証明書 をC言語構文に従い、文字列配列として定義します。
この際、証明書ヘッダーの最後に改行コードを付加します。
$ vi src/XMLParser.ino
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <NunniMCAX.h>
#include <datalink.h>
WiFiClientSecure https_client;
#define MAXLEN 256
static char m_characters[MAXLEN];
struct NunniMCAXContentHandler handler;
bool RootDetected = false;
void setup()
{
Serial1.begin(115200);
Serial1.println();
Serial1.print("Connecting to ");
Serial1.println(SECRET_SSID);
WiFi.begin(SECRET_SSID, SECRET_PASS);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial1.print(".");
}
Serial1.println("");
Serial1.println("WiFi connected");
Serial1.print("IP address: ");
Serial1.println(WiFi.localIP());
// set up the paser handler functions
handler.startDocument = startDocument;
handler.startElement = startElement;
handler.characters = characters;
handler.endElement = endElement;
handler.endDocument = endDocument;
getRSS();
}
void getRSS()
{
char get_cmd[256];
unsigned long timeout = millis();
// https://news.yahoo.co.jp/rss/topics/domestic.xml
const char* host = "news.yahoo.co.jp";
const char* page = "/rss/topics/domestic.xml";
int port = 443; // This should not be changed
https_client.setCACert(yahoo_co_jp_crt);
if (https_client.connect(host, port)) {
sprintf(get_cmd, "GET https://%s%s HTTP/1.1\r\nHost: %s\r\nUser-Agent: BuildFailureDetectorESP32\r\nConnection: close\r\n\r\n\0", host, page, host);
https_client.print(get_cmd);
https_client.flush();
while(https_client.available() == 0){
if(millis() - timeout > 5000){
Serial1.println(">>> Client Timeout !");
https_client.stop();
return;
}
}
} else {
Serial1.println("##https connection failed");
delay(5000);
return;
}
// パーサーの呼び出し
NunniMCAXparse( &getcFunc, &handler );
https_client.stop();
RootDetected = false;
delay(5000);
return;
}
int getcFunc()
{
while(!RootDetected) {
if (getChar() == '<') {
RootDetected = true;
return '<';
}
}
return getChar();
}
int getChar()
{
if (https_client.available() ) return https_client.read();
if (!https_client.connected()) return EOF;
}
int startDocument(void)
{
return 0;
}
int startElement( const char *tagname, struct NunniHashtable *args )
{
const int size = NunniHashtableSize( args );
char ** keys;
int i, ret;
const char *name, *value;
keys = (char**)calloc( size, sizeof( char * ) );
ret = NunniHashtableKeys( args, keys );
for ( i = 0; i < size; ++i ) {
name = keys[i];
value = NunniHashtableGet( args, name );
// Serial1.print(" attrName: ");
// Serial1.print(name);
// Serial1.print(" attrValue: ");
// Serial1.print(value);
}
memset( m_characters, 0, MAXLEN );
free(keys);
return 0;
}
int characters( char ch[], int start, int length )
{
int i = strlen( m_characters );
if ( i == MAXLEN ) return -1;
strncat( m_characters, &(ch[start]), length );
return 0;
}
int endElement( const char *tagname )
{
int len;
char *data = m_characters;
while( isspace( *data ) ) {
++data;
}
len = strlen( data );
while( isspace( data[--len] ) ) {
data[len] = 0;
}
if ( data != NULL && strncmp( data, "", 1 ) ) {
if ( (strncmp(tagname,"title",5)==0) || (strncmp(tagname,"link",4)==0) ) {
Serial1.println(data);
}
}
memset( m_characters, 0, MAXLEN );
return 0;
}
int endDocument(void)
{
return 0;
}
void loop() {}
$ pio run -t upload
デバイスモニターを起動して、プログラムを実行します。
$ pio device monitor -p /dev/ttyAMA0 -b 115200
Connecting to xxxxxxxxxxxx
.
WiFi connected
IP address: 192.168.13.56
Yahoo!ニュース・トピックス - 国内
https://news.yahoo.co.jp/topics/domestic?source=rss
岸田首相 北発射「容認できない」
https://news.yahoo.co.jp/pickup/6473916?source=rss
概算要求114兆円程度 過去最大に
https://news.yahoo.co.jp/pickup/6473904?source=rss
コロナ高額薬、一部自己負担へ
https://news.yahoo.co.jp/pickup/6473900?source=rss
関東大震災から6年後 東京の様子
https://news.yahoo.co.jp/pickup/6473925?source=rss
台風が沖縄接近 西日本は大雨恐れ
https://news.yahoo.co.jp/pickup/6473896?source=rss
最高検 供述誘導疑惑で検事聴取へ
https://news.yahoo.co.jp/pickup/6473895?source=rss
王座戦始まる 藤井竜王が八冠挑む
https://news.yahoo.co.jp/pickup/6473912?source=rss
三浦雄一郎さん90歳 富士山頂到達
https://news.yahoo.co.jp/pickup/6473899?source=rss
|
Raspberry Pi(ラズベリー パイ)は、ARMプロセッサを搭載したシングルボードコンピュータ。イギリスのラズベリーパイ財団によって開発されている。
たいていのことは100日あれば、うまくいく。長田英知著
「時間がなくて、なかなか自分のやりたいことができない」
「一念発起して何かを始めても、いつも三日坊主で終わってしまう」
「色んなことを先延ばしにしたまま、時間だけが過ぎていく」
そこで本書では、そんな著者が独自に開発した、
まったく新しい目標達成メソッド「100日デザイン」について、
その知識と技術を、余すところなくご紹介します。
まんがで納得ナポレオン・ヒル 思考は現実化する
OLとして雑務をこなす日々に飽き足らず、科学者だった父が残した薬品を商品化すべく、起業を決意した内山麻由(27)。彼女はセミナーで知り合った謎の女性からサポートを得ながら、彼女と二人三脚でナポレオン・ヒルの成功哲学を実践し、さまざまな問題を乗り越えていく。
ヒル博士の<ゴールデンルール>に従い、仕事に、恋に全力疾走する彼女の、成功への物語。
今日は人生最悪で最高の日 1秒で世界を変えるたったひとつの方法 ひすいこたろう著
偉人の伝記を読むと、最悪な日は、不幸な日ではなく、新しい自分が始まる日であることがわかります。最悪な出来事は、自分の人生が、想像を超えて面白くなる兆しなのです。偉人伝を読むことで、このときの不幸があったおかげで、未来にこういう幸せがくるのかと、人生を俯瞰する視線が立ち上がるのです。
ご飯は私を裏切らない heisoku著
辛い現実から目を背けて食べるご飯は、いつも美味しく幸せを届けてくれる。
29歳、中卒、恋人いない歴イコール年齢。バイト以外の職歴もなく、短期バイトを転々とする日々。ぐるぐると思索に耽るけど、ご飯を食べると幸せになれる。奇才の新鋭・heisokuが贈るリアル労働グルメ物語!
【最新版Gemini 3に対応!】できるGemini (できるシリーズ)
Geminiを「最強の知的生産パートナー」として使いこなすための、実践的なノウハウを凝縮した一冊です。
基本的な操作方法から、具体的なビジネスシーンでの活用、日々の業務を自動化するGoogle Workspaceとの連携、さらには自分だけのオリジナルAIを作成する方法まで余すところなく解説します。
Rustプログラミング完全ガイド 他言語との比較で違いが分かる!
Rustの各手法や考え方を幅広く解説!
500以上のサンプルを掲載。実行結果も確認。
全24章の包括的なチュートリアル。
ポチらせる文章術
販売サイト・ネット広告・メルマガ・ブログ・ホームページ・SNS…
全WEB媒体で効果バツグン!
カリスマコピーライターが教える「見てもらう」「買ってもらう」「共感してもらう」すべてに効くネット文章術
小型で便利な Type-C アダプター USB C オス - USB3.1 オスアダプター
Type-C端子のマイコンボードをこのアダプタを介して直接Raspberry Piに挿すことができます。ケーブルなしで便利なツールです。
Divoom Ditoo Pro ワイヤレススピーカー
15W高音質重低音/青軸キーボード/Bluetooth5.3/ピクセルアート 専用アプリ/USB接続/microSDカード
電源供給USBケーブル スリム 【5本セット】
USB電源ケーブル 5V DC電源供給ケーブル スリム 【5本セット】 電源供給 バッテリー 修理 自作 DIY 電子工作 (100cm)
|