質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
スクレイピング

スクレイピングとは、公開されているWebサイトからページ内の情報を抽出する技術です。

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

947閲覧

SwiftでHTMLの要素を複数取得したい(iOS)

BlackJack

総合スコア7

スクレイピング

スクレイピングとは、公開されているWebサイトからページ内の情報を抽出する技術です。

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2018/02/19 12:35

編集2018/02/20 00:11

前提・実現したいこと

Swift(iOS)でHTML内の要素<p>タグを複数取得するソフトウェアを作っています。
JiやKannaなどのライブラリで実装中に以下の問題が発生しました。

発生している問題

JiやKannaでは最初の要素、例えば「<p>内容</p>」で「内容」は問題なく取得できるのですが、 「<p>内容</p><p>内容2</p><p>内容3</p>」 となっていた場合に、内容2や内容3を取る方法が分かりません。 node.firstで最初の要素は取れます。しかし二番目以降の要素の取り方がわからず困っております。 何卒ご教示宜しくお願いいたします。

該当のソースコード

Swift

1 /// スクレイピング 2 func parseHtml(data: Data) -> String? { 3 // KannaでHTMLDocumentを生成 4 guard let doc = HTML(html: data, encoding: String.Encoding.utf8) else { 5 fatalError("Error: HTML") 6 } 7 var retData: String? = "" 8 // HTMLの<table>の時刻の列を基準にLoopし、該当行の気温の列をKannaでスクレイピング 9 let node = doc.xpath("//p[@class='text']") 10 if let nodeFirst = node.first, var content:String? = nodeFirst.content { 11 // 値が入っている場合のみ取得 12 retData = content! 13 return retData! 14 } 15 return retData! 16 } 17

試したこと

JiやKannaのライブラリ自体の内容を書き換えようとしたのですが、該当箇所が見つかりませんでした。
また、外側の大きなタグから本文を取得すると、余計な文章が入ったり、記事によってはタグが違って
取得できなかったりしました。

補足情報(FW/ツールのバージョンなど)

Swift3.0で開発しております。
Xcode9で、Kannna、Jiともに最新版です。
とにかく配列などで<p>タグを全部取得したいです。
最終的には文字列で結合したいと思っております。
どうかご教示宜しくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

こういうことですか?
node(XPathObject型)はSequenceプロトコル準拠なので順番に取り出せばいいですよ。

swift

1print("count =", node.count) 2node.forEach { 3 print($0.content ?? "nil") 4} 5//=> count = 3 6//=> 内容 7//=> 内容2 8//=> 内容3

おまけ

swift

1let joined = node.flatMap {$0.content}.joined(separator: ",") 2print(joined) 3//=> 内容,内容2,内容3

投稿2018/02/20 01:42

fuzzball

総合スコア16731

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

BlackJack

2018/02/20 10:13

ご回答くださりどうもありがとうございます。 順番に取り出すことが可能なんですね。 試したみたところ、問題なく複数ある<p>タグを全部取得することができました! これでソフトウェア開発が進むと思います。 本当に感謝いたします、どうもありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問