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

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

新規登録して質問してみよう
ただいま回答率
85.48%
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

1回答

1777閲覧

PHPのスクレイピングでループの初期値を変える

dokoniarukana

総合スコア31

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2016/12/20 04:50

編集2016/12/20 05:33

Goutteを使用しています。

以下のようなソースからデータを抽出しています。

<tr>の中には<td>が複数あって一番最初のtdだけを取ります。 ``` <table id="main"> <tr class="111">...</tr> <tr class="aaa">...</tr> <tr class="AAA">...</tr> <tr>...</tr> <tr>...</tr> <tr>...</tr> <tr>...</tr> <tr>...</tr> <tr>...</tr> <tr>...</tr>
```ここに言語を入力 $list = []; $site->Filter('table#main')->Filter('tr')->each(function($node)use(&$list) { $list [] = $node->Filter('td')->eq(0)->text(); }); var_dump($list);

tableの中身が全てただのtrであれば上記のコードでいけるんですが、
最初のclass付きのtr3つが邪魔をしていてループ出来ない状態です。

<b>Fatal error</b>: Uncaught exception 'InvalidArgumentException' with message 'The current node list is empty.'

4つ目のclassの無いtrからループを開始したいのですが
この場合の記述はどう加えたら良いのでしょうか。

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

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

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

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

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

guest

回答1

0

ベストアンサー

class属性がないtrを取得したいなら、filterXPathでnotを使えばできると思います。

php

1$crawler->filterXPath('//table[@id="main"]/tr[not(@class)]')

※filterでもできるかもですが...

以下、動くサンプルコード

php

1use Symfony\Component\DomCrawler\Crawler; 2 3$html = ' 4<table id="main"> 5<tr class="111"><td>111</td></tr> 6<tr class="aaa"><td>aaa</td></tr> 7<tr class="AAA"><td>AAA</td></tr> 8<tr><td>...</td></tr> 9<tr><td>...</td></tr> 10<tr><td>...</td></tr> 11<tr><td>...</td></tr> 12<tr><td>...</td></tr> 13<tr><td>...</td></tr> 14<tr><td>...</td></tr> 15</table> 16'; 17$crawler = new Crawler($html); 18 19$list = $crawler->filterXPath('//table[@id="main"]/tr[not(@class)]')->each(function($node) { 20 return $node->Filter('td')->eq(0)->text(); 21}); 22var_dump($list);

(追記)
もしくは4番目以降取りたいならposition()を使う方法もあります

php

1$crawler->filterXPath('//table[@id="main"]/tr[position() >= 4]')

投稿2016/12/20 05:02

編集2016/12/20 05:08
popobot

総合スコア6586

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

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

dokoniarukana

2016/12/20 05:09

Fatal error: Call to undefined method GetPage::filterXPath() と出てしまいました。
popobot

2016/12/20 05:13

GetPageというGoutteのクラスはないので、独自に拡張されているのではないかと...
popobot

2016/12/20 05:15

以下のコードで動くかもしれませんね $site->Filter('table#main')->filterXPath('table/tr[not(@class)]')
dokoniarukana

2016/12/20 05:32

Fatal error: Call to a member function filterXPath() on string in 試してみましたがこのようなエラーでした。 PHPは初心者以前のレベルなので色々と勉強する必要がありそうです…。 しばらくしたらベストアンサーとさせていただきます。 また十分に理解してから出直そうと思います。
popobot

2016/12/20 05:49

以下だったらどうですか? CSSセレクタ版です $crawler->Filter('table#main')->Filter('tr:not([class])')
dokoniarukana

2016/12/20 05:53

Fatal error: Call to a member function Filter() でした 何がいけないのかさっぱりわからないです。
popobot

2016/12/20 05:54

すみません、変数間違えました... 以下ですね。 $site->Filter('table#main')->Filter('tr:not([class])')
dokoniarukana

2016/12/20 05:58

$list = $site->Filter('table#main')->Filter('tr:not([class])')->each(function($node) { return $node->Filter('td')->eq(0)->text(); }); var_dump($list); ↑実際のコードで Fatal error: Uncaught exception 'InvalidArgumentException' with message ' The current node list is empty.' でした
popobot

2016/12/20 06:02

コードはあっていると思いますので、Goutteのバージョンが古いとかかもしれませんね 自分の環境は最新のv3.2.0でした。
dokoniarukana

2016/12/20 06:10

そうなんですね!会社の人に相談してみます! 長々とお付き合い頂きとありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問