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

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

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

HttpWebRequestとは.NETにおけるクラスであり、WebRequestクラスをHTTPに導入するものです。

HTTPヘッダー

Hypertext Transfer Protocol(HTTP)の中のHTTPヘッダフィールドはHTTPの要求やレスポンスの機能しているパラメーターが含まれます。その要求もしくはレスポンスライン(メッセージの最初の一行)でメッセージヘッダを作ります。

PHP

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

Q&A

解決済

1回答

5062閲覧

PHPを使ったWebスクレイピングのアクセスについて

TakuyaHidaka

総合スコア137

HttpWebRequest

HttpWebRequestとは.NETにおけるクラスであり、WebRequestクラスをHTTPに導入するものです。

HTTPヘッダー

Hypertext Transfer Protocol(HTTP)の中のHTTPヘッダフィールドはHTTPの要求やレスポンスの機能しているパラメーターが含まれます。その要求もしくはレスポンスライン(メッセージの最初の一行)でメッセージヘッダを作ります。

PHP

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

0グッド

1クリップ

投稿2016/04/09 03:28

PHPのWebスクレイピングで、分からない点があって困っています。

以下のコードですが、あるサイトにアクセスして取り出したデータを元に、さらに次のページへアクセスするというものですが、コメント部のSTEP1では、対象のデータを正規表現で取り出すことに成功していますが、
続くSTEP2で、STEP1で抽出したデータを使用しても、

PHP Warning: file_get_contents(http://www.bosch.co.jp/jp/aa/fit_search/step-2.asp): failed to open stream: HTTP request failed! HTTP/1.1 500 Internal Server Error

と出てしまい、アクセスすることができないのです。

本当ならば、
http://www.bosch.co.jp/jp/aa/fit_search/**step-2.asp?for_domestic=yes&fit_group=31**
という形でアクセスしたいです。

どなたかこれの解決方法をご教授いただけないでしょうか?
よろしくお願い致します。

PHP

1<?php 2/** 3 * Web Scraping 4 */ 5 6require_once 'simple_html_dom.php'; 7 8class sample { 9 10 public $list = array(); 11 12 /** 13 * __construct 14 */ 15 function __construct() { 16 $this->getList(); 17 } 18 19 /** 20 * 指定したURLにデータとPOSTを送信 21 */ 22 function post($url, $data) { 23 $headers = array('Content-Type: application/x-www-form-urlencoded'); 24 $options = array('http' => array( 25 'method' => 'POST', 26 'content' => http_build_query($data), 27 'header' => implode("\r\n", $headers), 28 )); 29 return file_get_contents($url, false, stream_context_create($options)); 30 } 31 32 /** 33 * 取得する全リストを取得 34 */ 35 function getList() { 36 37 // Step 1 38 $url = 'http://www.bosch.co.jp/jp/aa/fit_search/step-1.asp'; 39 $data = array( 40 'none' => '' 41 ); 42 $html = str_get_html($this->post($url, $data)); 43 $script = $html->find('ul[id=groupList_category_2_domestic]', 0); 44 preg_match_all('/<a href=".\/(.+?)"*>/', $script, $matches_1); 45 46 foreach ($matches_1[1] as $v) { 47 preg_match('/.*=(.+?)&.*/', $v, $for_inout); 48 preg_match('/.*=([1-9]{1}[0-9]{0,1})/', $v, $fit_group); 49 $data = array( 50 'for_domestic' => $for_inout, 51 'fit_group' => $fit_group, 52 ); 53 54 // Step 2 55 $url = 'http://www.bosch.co.jp/jp/aa/fit_search/step-2.asp'; 56 $html = str_get_html($this->post($url, $data)); 57 } 58 59 $html->clear(); 60 unset($html); 61 } 62 63} 64 65$a = new sample();

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

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

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

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

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

guest

回答1

0

ベストアンサー

http://www.bosch.co.jp/jp/aa/fit_search/step-2.asp?**for_domestic=yes&fit_group=31**

ならなぜPOSTしているのでしょうか?これはGETのリクエストですが…
(対象サイトを普通にWebブラウザで見て利用してみましたが,通信ログを見る限りGETリクエストしか取り扱ってないかと…)

php

1public function get($url, array $data = []) { 2 return file_get_contents($url . '?' . http_build_query($data, '', '&')); 3}

このメソッドを使えばいいです.
(ただ,file_get_contentsはHTTP/1.0にてTCPコネクションを再利用しないようになっているので,cURLを使ったコードに変えてHTTP/1.1でTCPコネクションを再利用するようにしたほうが,サイトに対する負荷も実行時間も短くなりますので,書き換えをおすすめします)


【蛇足】

こういうクラス作っておくと使い勝手いいと思います.

php

1<?php 2 3class Scraper 4{ 5 private $ch; 6 7 public function __construct() 8 { 9 $this->ch = curl_init(); 10 curl_setopt_array($this->ch, [ 11 CURLOPT_COOKIEFILE => '', 12 CURLOPT_FAILONERROR => true, 13 CURLOPT_RETURNTRANSFER => true, 14 CURLOPT_FOLLOWLOCATION => true, 15 ]); 16 } 17 18 public static function createDOMXPath($content) 19 { 20 $dom = new \DOMDocument; 21 @$dom->loadHTML($content); 22 return new \DOMXPath($dom); 23 } 24 25 public function get($url, array $params = []) 26 { 27 curl_setopt_array($this->ch, [ 28 CURLOPT_URL => $url . '?' . http_build_query($params, '', '&'), 29 CURLOPT_HTTPGET => true, 30 ]); 31 $response = curl_exec($this->ch); 32 if ($response === false) { 33 throw new \RuntimeException(curl_error($this->ch)); 34 } 35 return $response; 36 } 37 38 public function post($url, array $params = []) 39 { 40 curl_setopt_array($this->ch, [ 41 CURLOPT_URL => $url, 42 CURLOPT_POST => true, 43 CURLOPT_POSTFIELDS => http_build_query($params, '', '&'), 44 ]); 45 $response = curl_exec($this->ch); 46 if ($response === false) { 47 throw new \RuntimeException(curl_error($this->ch)); 48 } 49 return $response; 50 } 51 52 public function getXPath($url, array $params = []) 53 { 54 return self::createDOMXPath($this->get($url, $params)); 55 } 56 57 public function postXPath($url, array $params = []) 58 { 59 return self::createDOMXPath($this->post($url, $params)); 60 } 61 62}

投稿2016/04/09 04:14

編集2016/04/09 04:35
mpyw

総合スコア5223

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

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

mpyw

2016/04/09 04:17

蛇足ですが,Simple HTML DOM Parser を使ったCSSセレクタと正規表現のゴリ押しが入り乱れていて,パース方法に一貫性が無いように思います.私だったらPHP標準のDOMXPathだけで済ませちゃいますね. http://qiita.com/mpyw/items/c0312271819baee09132
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問