【发布时间】:2017-04-06 06:22:43
【问题描述】:
经过一段时间的尝试,我不得不问。它快把我逼疯了。我写了一个小脚本来抓取 mobile.bahn.de 以获取当地火车站的出发信息。
我正在使用 CURLOPT_COOKIEFILE 和 Cookie Jar,但秒请求不在远程 Web 服务器上的会话中。
/* Display real time information for a specific connection by scraping mobile.bahn.de */
require_once("simple_html_dom.php");
function departure_in_seconds($from, $to, $connection_number){
// html on mobile.bahn.de is weird. So wi
$row_number = ($connection_number+1) * 2 - 2;
$date = date('d.m.y');
$time = date('H:i');
// set post fields
$post = [
'queryPageDisplayed' => 'yes',
'REQ0JourneyStopsS0A'=> 1,
'REQ0JourneyStopsS0G' => $from,
'REQ0JourneyStopsS0ID' => '',
'locationErrorShownfrom' => 'yes',
'REQ0JourneyStopsZ0A' => 1,
'REQ0JourneyStopsZ0G' => $to,
'REQ0JourneyStopsZ0ID' => '',
'locationErrorShownto' => 'yes',
'REQ0JourneyDate' => $date,
'REQ0JourneyTime' => $time,
'existOptimizePrice' => 1,
'REQ0HafasOptimize1' => '0:1',
'rtMode' => 12,
'existRTMode' => 1,
'immediateAvail' => 'ON',
'start' => 'Suchen'
];
/* post form fields to mobile.bahn.de */
$html = url_to_dom('https://mobile.bahn.de/bin/mobil/query.exe/dox', $post);
/* Scrape the correct train connection from HTML */
$connection = str_get_html($html->find('.scheduledCon',$row_number));
/* Find departure time information in connection HTML snippet */
$departure_time_string = $connection->find('.bold',0)->plaintext;
/* Find delay information in connection HTML snippet */
$delay_string = $connection->find('.okmsg',0);
$delay = preg_replace("/[^0-9]/","",$delay_string);
$delay_seconds = $delay*60;
/* Calculate the time until departure in seconds. */
$departure_in_seconds = strtotime($departure_time_string) + $delay_seconds - strtotime('now');
/* Find link to train connection detail information page */
$connection_details_url = ($connection->find('a',0)->href);
/* THIS DOES NOT WORK! WHY?? The response is not the correct HTML */
/* Scrape this connection detail url */
$connection_details_html = url_to_dom($connection_details_url);
echo $connection_details_html;
/* Find the trainline in the HTML snippet */
$trainline = $connection_details_html->find('.motSection',0);
/* Return all information */
return $departure_time_string.' Delay:'.$delay.' Train line:'.$trainline;
}
function url_to_dom($href, $post = false) {
/*store temporary cookie files */
$cookie_jar = tempnam('/tmp','cookie');
$curl = curl_init();
/* if $post is set sent this posdt fields as a post request */
if( $post ){
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($post));
curl_setopt($curl, CURLOPT_POST, true);
}
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($curl, CURLOPT_COOKIEFILE, $cookie_jar);
curl_setopt($curl, CURLOPT_COOKIEJAR, $cookie_jar);
curl_setopt($curl, CURLOPT_URL, $href);
$str = curl_exec($curl);
curl_close($curl);
// Create a DOM object
$dom = new simple_html_dom();
// Load HTML from a string
$dom->load($str);
return $dom;
}
echo departure_in_seconds('Langenfelde', 'Altona', 0).'<br>';
在github上:https://github.com/mtoensing/time2train/blob/1.2/index.php
这个概念证明有效。基本上。
- 首先我发布表单数据以检索结果页面。
- 其次,我点击该结果页面上的链接到旅程详细信息。
但是最后一步不起作用。我得到的 html 数据只是首页。我的猜测是 cURL 没有会话 ID。但我设置了所有 cURL 选项,如 cookiejar 和 cookiefile。
有什么想法吗?我不认为这是防止抓取数据的保护措施。我认为这里的限制是我的编码技能以及我对会话和 cookie 的缺失知识。 ;-)
【问题讨论】:
标签: php session curl web-scraping