Получить частичную веб-страницу - PullRequest
3 голосов
/ 08 октября 2009

Есть ли способ ограничения количества данных, которые CURL будет получать? Я соскребаю данные со страницы размером 50 КБ, однако данные, которые мне нужны, находятся в верхней четверти страницы, поэтому мне нужно только извлечь первые 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 или открою загрузку www.website.com в память, означая, что я все равно буду передавать полные 50 КБ?

Ответы [ 4 ]

4 голосов
/ 08 октября 2009

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

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

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

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

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

3 голосов
/ 08 октября 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 для отправки файла? .

2 голосов
/ 08 октября 2009

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

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

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

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

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

0 голосов
/ 08 октября 2009

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

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

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

  • длина прочитано байтов
...