Получить частичную веб-страницу

Есть ли способ ограничить объем данных, которые CURL будет извлекать? Я соскребаю данные со страницы размером 50 КБ, однако данные, которые мне нужны, находятся в верхней 1/4 страницы, поэтому мне действительно нужно получить только первые 10 КБ страницы.

Я спрашиваю, потому что мне нужно отслеживать много данных, что приводит к передаче около 60 ГБ данных в месяц, когда релевантно только около 5 ГБ этой пропускной способности.

Я использую PHP для обработки данных, однако у меня гибкий подход к извлечению данных, я могу использовать CURL, WGET, fopen и т. д.

Один подход, который я рассматриваю, это

$fp = fopen("http://www.website.com","r");
fseek($fp,5000);
$data_to_parse = fread($fp,6000);

Означает ли вышеизложенное, что я буду передавать только 6 КБ с www.website.com, или fopen загрузит www.website.com в память, что означает, что я все равно буду передавать полные 50 КБ?


person James    schedule 08.10.2009    source источник


Ответы (4)


Вы также можете выполнить то, что ищете, используя CURL.

Если вы посмотрите документацию для CURLOPT_WRITEFUNCTION, вы можете зарегистрировать обратный вызов, который вызывается всякий раз, когда данные доступны для чтения из CURL. Затем вы можете подсчитать полученные байты, и когда вы получите более 6000 байтов, вы можете вернуть 0, чтобы прервать оставшуюся часть передачи.

В документации libcurl обратный вызов описан немного подробнее:

Эта функция вызывается libcurl, как только получены данные, которые необходимо сохранить. Возвращает количество фактически обработанных байтов. Если эта сумма отличается от суммы, переданной вашей функции, она сообщит библиотеке об ошибке, прервет передачу и вернет CURLE_WRITE_ERROR.

Функция обратного вызова будет передавать как можно больше данных во всех вызовах, но вы не можете делать никаких предположений. Это может быть один байт, это могут быть тысячи.

person Keith Palmer Jr.    schedule 08.10.2009
comment
Я отметил это как принятый ответ, поскольку он более надежен, чем запрос диапазона HTTP, который не всегда может поддерживаться, и я могу отметить только один ответ. - person James; 09.10.2009

На самом деле это скорее HTTP, чем вопрос CURL.

Как вы уже догадались, если вы используете fopen, будет загружена вся страница. Неважно, ищете ли вы по смещению 5000 или нет.

Лучший способ добиться желаемого — использовать частичный запрос HTTP GET, как указано в HTML RFC (http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html):

Семантика метода GET изменяется на «частичный GET», если сообщение запроса включает поле заголовка Range. Частичный GET запрашивает передачу только части объекта, как описано в разделе 14.35. Частичный метод GET предназначен для уменьшения ненужного использования сети, позволяя выполнять частично извлеченные объекты без передачи данных, уже имеющихся у клиента.

Детали частичных запросов GET с использованием диапазонов описаны здесь: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35.2

person NewbiZ    schedule 08.10.2009

попробуйте выполнить HTTP-запрос RANGE:

GET /largefile.html HTTP/1.1
Range: bytes=0-6000

если сервер поддерживает диапазон запросов, он вернет код ответа 206 Partial Content с заголовком Content-Range и запрошенным диапазоном байтов (если это не так, он вернет 200 и весь файл). см. http://benramsey.com/archives/206-partial-content-and-range-requests/ для хорошего объяснения запросов диапазона.

см. также Возобновляемые загрузки при использовании PHP для отправки файла?.

person ax.    schedule 08.10.2009

Он загрузит всю страницу с вызовом fopen, но затем прочитает только 6 КБ с этой страницы.

Из руководства по PHP:

Чтение прекращается, как только выполняется одно из следующих условий:

  • Прочитано длина байт
person James Skidmore    schedule 08.10.2009