現在PHPの勉強をしている者です。
勉強目的でスクレイピングを行うサイトを作成しています。
単純なサイトの記事タイトル・記事URLを取得して
mysqlにてデータベースに保存するという事は作成する事が出来ました。
次に、2段階のスクレイピングとして
トップページにてURLを取得して、
次にそのURLにアクセスして記事タイトルや投稿日時を取得して
mysqlにてデータベースに保存するという事もできるようになりました。
そこで今回、
スクレイピングによってトップページにあるリンクを複数取得して
次に1個1個のURLにアクセスしてそこで記事タイトルや画像のURLを取得するといったサイトを作成しています。
途中までは今までの勉強と似ている内容でしたので順調にいっていたのですが
エラーが発生していました。
【問題が発生して上手く行かない時の内容】
記事のタイトルや投稿日時等の情報を取得した時に
自動的に「空白の行」が追加されてしまいます。
最初はvar_dump()にて表示されていて
echoでは表示されていなかったので、試しにmysqlにて保存してみると
mysqlにも空白の行が追加されてしまっていました。
これだとデータベースでの操作で思ったような挙動が出来ないので
スクレイピングを行った時に自動的に空白の行が追加されないようにしたいです。
作成したコードです。
PHP
1try { 2 $db = new \PDO(DSN, DB_USERNAME, DB_PASSWORD); 3 $db->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); 4 echo "データベースへの接続が出来ました"; 5}catch (\PDOException $e) { 6 7 echo $e->getMessage(); 8 exit; 9} 10 11require_once(__DIR__ . '/phpQuery-onefile.php'); 12 13// WEB用のスクレピングのURL 14$html = "取得したいサイトのURL"; 15 16//cURLセッションを初期化する 17$ch = curl_init(); 18 19//URLとオプションを指定する 20curl_setopt($ch, CURLOPT_URL, $html); 21curl_setopt($ch, CURLOPT_HEADER, false ); 22curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 23curl_setopt($ch, CURLOPT_TIMEOUT, 30); 24 25//URLの情報を取得する 26$html = curl_exec($ch); 27 28$doc = phpQuery::newDocument(mb_convert_encoding($html, 'HTML-ENTITIES', 'Shift_JIS')); 29 30// var_dump($doc); 31 32$i = 0; 33foreach ($doc[".MENU"] as $entry){ 34 35//ループ回数が5回を超えたらforeachを抜けます。 36if ($i >= 5 ) { 37 break; 38}else { 39 $i++; 40} 41 42//URLを取得 43$url1 = pq($entry)->find('p > a:eq(0)')->attr("href"); 44 45//URLを取得 46$url2 = pq($entry)->find('p > a:eq(2)')->attr("href"); 47 48//URLを取得 49$url3 = pq($entry)->find('p > a:eq(4)')->attr("href"); 50 51//次のスクレピングを行う為に、配列に追加してみました。 52$html2 = [ 53 $url1, 54 $url2, 55 $url3, 56]; 57 58} 59 60//配列の中にあるURLの数だけスクレピングを行いたいのでこのように設置しています。 61foreach($html2 as $html3) { 62 63 //cURLセッションを初期化する 64 $ch = curl_init(); 65 66 //URLとオプションを指定する 67 curl_setopt($ch, CURLOPT_URL, $html3); 68 curl_setopt($ch, CURLOPT_HEADER, false ); 69 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 70 curl_setopt($ch, CURLOPT_TIMEOUT, 30); 71 72 //URLの情報を取得する 73 $html3 = curl_exec($ch); 74 75 $doc = phpQuery::newDocument(mb_convert_encoding($html3, 'HTML-ENTITIES', 'Shift_JIS')); 76 77 $j = 0; 78 foreach ($doc[".container"] as $entry2){ 79 80//ループ回数が5回を超えたらforeachを抜けます。 81 if ($j >= 5 ) { 82 break; 83 }else { 84 $j++; 85 } 86 87// タイトル取得 88$title = pq($entry2)->find('.title:eq(0)')->text(); 89 90echo "<br />"; 91var_dump($title); 92 93// URL 94$url99 = pq($entry2)->find('.menuurl > a:eq(1)')->attr("href"); 95 96echo "<br />"; 97var_dump($url99); 98 99//mysqlに取得したタイトルとURLを書き込みで保存します。 100$sql = "insert into bbs (title, url, 101created) values (:title,:url,now()) 102ON DUPLICATE KEY UPDATE 103created = now() 104"; 105$stmt = $db->prepare($sql); 106$stmt->execute([ 107 ':title' => $title, 108 ':url' => $url99 109]); 110 111} 112} 113//セッションを終了する 114curl_close($ch); 115
プログラムの組み方に間違いがあり上手くいっていません。:
このように空白の行(string(0) "")が取得する度に入ってしまいます。
今回はタイトルとURLを取得しているので
2つの行のstring(0) ""が入ってしまっています。
string(0) "" string(0) "" string(161) "【ネット】新潟・米山隆一知事が石平氏投稿に「吐き気を催すほど醜悪」とツイート。「差別発言だ」との批判相次ぐ " string(54) "http://site-1.html" string(0) "" string(0) "" string(83) "【北朝鮮】アントニオ猪木議員、朝鮮労働党副委員長と会談 " string(54) "http://site-2.html" string(0) "" string(0) "" string(191) "【このハゲー!】豊田議員「辞めない」「必死で働き償う」" string(54) "http://site-3.html"
mysqlにて保存を行った際にも「空白の行」が間に挿入されてしまいます。
これだとサイトに表示する際やデータベースの操作でも問題が起きてしまうので
なんとか「スクレイピングを実施した際に空白の行が入らない」ようにする為に
試行錯誤を何度も行ったのですが上手くいきません。
解決方法をご存知の方や
何かお気付きの点がありましたら教えて頂けると、とても嬉しいです。
お力をお貸し頂けたら嬉しいです。
どうかよろしくお願いします。
回答1件
あなたの回答
tips
プレビュー