pagetaka

写真、PC、ネット、岡山、旅の話題をお届けします

PHP:正規表現でaタグhref要素のリンク先抽出。条件式で文字列処理も使った。

PHPでDOMとかWEBスクレイピングというようなことをやって、RSSがないサイトでも記事更新状況取得を実現したいと妄想・幻想を抱いている耄碌爺です。
目的サイトでaタグの使い方が一般的な書式ではNGとなる例に当たり、単純な正規表現では「href=」に続くリンク先URLを取得できない場合があることがわかりました。
昨日だいぶやってみたですけどダメでした。

「"」がない、「target」属性などの記載もあったり…

本来であれば「href="URL"」などと記載するところを「href=URL」とセットになっていたんですが、ブラウザがエラーを吸収し、ちゃんとリンク先に飛んでいくのを確認したのが、昨日でありました。
ということで、それをくみこんだ正規表現を考えたのですが、うまくいかない場合もある。その上、「href」の前後に「ref」「target」などが書かれることもある。結果的にその順番もどうでも良いみたいなことになっている。
ということで、昨夜はふて寝したです・

aタグ内のhref要素でありそうな記述

で、試してみたのが、以下の13種類でした。

$texts[0]='<a rel=\"uuu\" href="http://a.jp">x-site</a>';
$texts[1]='<a rel\"uuu\" href="http://b.jp" >x-site</a>';
$texts[2]='<a rel=\"uuu\" href=http://c.jp">x-site</a>';
$texts[3]='<a rel\"uuu\" href=http://d.jp" >x-site</a>';
$texts[4]='<a rel=uuu href=http://e.jp>x-site</a>';
$texts[5]='<a rel\"uuu\" href=http://f.jp >x-site</a>';
$texts[6]='<a href="http://g.jp" target="ddd">x-site</a>';
$texts[7]='<a rel\"uuu\" href=http://h.jp target="ddd">x-site</a>';
$texts[8]='<a href="/abc.html" target="ddd">x-site</a>';
$texts[9]='<a href="./efg.html" target="ddd">x-site</a>';
$texts[10]='<a href="../hij.html" target="ddd">x-site</a>';
$texts[11]='<a href=../klm.html target="ddd">x-site</a>';
$texts[12]='<a > </a>';

最後(13番目)の[12]はうまく無視するようになればOKということも考慮したです。

正規表現と、PHPの文字列処理を条件を変えながらやってみた結果

上の[0]と下の「1=」が対になります。

1=http://a.jp
2=http://b.jp
3=http://c.jp
4=http://d.jp
5=http://e.jp
6=http://f.jp
7=http://g.jp
8=http://h.jp
9=/abc.html
10=/efg.html
11=/hij.html
12=/klm.html

最後(13番目)の[12]はムシ…。

trim、strpos、substr

正規表現のキモと続き部分は以下の通りです。

preg_match("|href=\"{0,}(.*?)\"{0,}\.*>|mis",$text,$parts);	
@$parts[1] = strtr($parts[1],"\""," "); //@=エラームシ

$parts[1]にマッチした文字列(URL以外も含まれる)が代入されます。それをさらにイロイロこねくりまわし、結果を得ようとしたのでありました。
2行目では、上の正規表現で取得した結果に「"」が残るので、半角空白と置換する、という作業をやっています。
使った関数は3つでした。

  • trim 空白または指定した文字が、対象文字列の外側にあればとってくれる
  • strpos 指定した文字が、対象文字列のどの位置で出現するか教えてくれる
  • substr 対象文字列から、指定した文字列を抽出取得する

さあ、これをつかって、DOMでリンク先が取得できないということがないように、スクリプトに組み込まなくては…。
本日は、もうツカレタ…。zzzzz~