В прошлом выпуске мы говорили о необходимости использования Java для создания сканера Zhihu, поэтому на этот раз мы изучим, как использовать код для получения содержимого веб-страницы.
Прежде всего, если у вас нет опыта работы с HTML, CSS, JS и AJAX, рекомендуется зайти на W3C (нажмите на меня, нажмите на меня), чтобы немного подучиться.
Говоря о HTML, здесь возникает проблема доступа GET и доступа POST.
Если вам не хватает понимания этого аспекта, вы можете прочитать статью W3C: «GET против POST».
Ага, не буду здесь вдаваться в подробности.
Затем нам нужно использовать Java для сканирования содержимого веб-страницы.
На этот раз нам пригодится наш Baidu.
Правильно, он больше не неизвестный тестер скорости Интернета, он вот-вот станет нашей морской свинкой-рептилией! ~
Давайте сначала взглянем на домашнюю страницу Baidu:
Думаю, всем известно, что такая страница — результат совместной работы HTML и CSS.
Щелкаем правой кнопкой мыши по странице в браузере и выбираем «Просмотреть исходный код страницы»:
Правильно, это что-то вроде этого. Это исходный код страницы Baidu.
Наша следующая задача — использовать наш сканер, чтобы получить то же самое.
Давайте сначала посмотрим на простой исходный код:
импортировать java.io.*;
импортировать java.net.*;
общественный класс Main {
public static void main(String[] args) {
// Определить ссылку, которую нужно посетить
Строка URL = "http://www.baidu.com";
//Определяем строку для хранения содержимого веб-страницы
Строковый результат = "";
//Определяем буферизованный поток ввода символов
BufferedReader в = ноль;
пытаться {
//Преобразуем строку в объект URL
URL-адрес realUrl = новый URL-адрес (url);
// Инициализируем ссылку на этот URL
Соединение URLConnection = realUrl.openConnection();
// Запускаем фактическое соединение
соединение.подключиться();
//Инициализируем входной поток BufferedReader для чтения ответа URL
in = новый BufferedReader (новый InputStreamReader (
Connection.getInputStream()));
// Используется для временного хранения данных каждой захваченной строки
Струнная линия;
while ((line = in.readLine()) != null) {
//Обходим каждую захваченную строку и сохраняем ее в результате
результат += строка;
}
} catch (Исключение е) {
System.out.println("Исключение при отправке запроса GET!" + e);
е.printStackTrace();
}
// Используйте наконец, чтобы закрыть входной поток
окончательно {
пытаться {
если (в != ноль) {
в.закрыть();
}
} catch (Исключение e2) {
e2.printStackTrace();
}
}
System.out.println(результат);
}
}
Вышеупомянутое представляет собой Java-симуляцию доступа к методу Main Baidu.
Вы можете запустить его, чтобы увидеть результаты:
Ага, это точно то же самое, что мы видели в браузере ранее. На этом этапе простейший обходчик готов.
Но не все в такой большой куче вещей может быть тем, что мне нужно. Как я могу получить от нее то, что хочу?
Возьмем, к примеру, логотип Baidu с большой лапой.
Временные потребности:
Получите ссылку на изображение большой лапы логотипа Baidu.
Давайте сначала поговорим о методе просмотра в браузере.
Щелкните изображение правой кнопкой мыши и выберите «Проверить элементы» (Firefox, Google и IE11 имеют эту функцию, но имена разные):
Ага, вы можете увидеть плохой тег img, окруженный множеством элементов div.
Этот src является ссылкой на изображение.
Итак, как нам это сделать в Java?
Обратите внимание заранее, что для облегчения демонстрации кода все коды не инкапсулированы по классам, пожалуйста, поймите.
Давайте сначала инкапсулируем предыдущий код в функцию sendGet:
импортировать java.io.*;
импортировать java.net.*;
общественный класс Main {
статическая строка sendGet (URL-адрес строки) {
//Определяем строку для хранения содержимого веб-страницы
Строковый результат = "";
//Определяем буферизованный поток ввода символов
BufferedReader в = ноль;
пытаться {
//Преобразуем строку в объект URL
URL-адрес realUrl = новый URL-адрес (url);
// Инициализируем ссылку на этот URL
Соединение URLConnection = realUrl.openConnection();
// Запускаем фактическое соединение
соединение.подключиться();
//Инициализируем входной поток BufferedReader для чтения ответа URL
in = новый BufferedReader (новый InputStreamReader (
Connection.getInputStream()));
// Используется для временного хранения данных каждой захваченной строки
Струнная линия;
while ((line = in.readLine()) != null) {
// Проходим каждую захваченную строку и сохраняем ее в результате
результат += строка;
}
} catch (Исключение е) {
System.out.println("Исключение при отправке запроса GET!" + e);
е.printStackTrace();
}
// Используйте наконец, чтобы закрыть входной поток
окончательно {
пытаться {
если (в != ноль) {
в.закрыть();
}
} catch (Исключение e2) {
e2.printStackTrace();
}
}
вернуть результат;
}
public static void main(String[] args) {
// Определить ссылку, которую нужно посетить
Строка URL = "http://www.baidu.com";
//Открываем ссылку и получаем содержимое страницы
Строковый результат = sendGet(url);
System.out.println(результат);
}
}
Это выглядит немного опрятнее, пожалуйста, простите мое обсессивно-компульсивное расстройство.
Следующая задача — среди множества полученных вещей найти ссылку на картинку.
Первый метод, который мы можем придумать, — это использовать функцию indexof для поиска подстрок String в строковом результате исходного кода страницы.
Да, этот метод может медленно решить эту проблему, например, напрямую indexOf("src"), чтобы найти начальный серийный номер, а затем быстро получить конечный серийный номер.
Однако мы не всегда можем использовать этот метод. Ведь соломенные сандалии годятся только для ходьбы. Позже нам еще придется отрезать протезы ног, чтобы удерживать головы.
Пожалуйста, простите мое вторжение и продолжайте.
Так как же нам найти источник этой картинки?
Правильно, как сказала публика внизу, регулярное совпадение.
Если кто-то из учащихся не уверен в регулярных выражениях, вы можете обратиться к этой статье: [Python] Web Crawler (7): Учебное пособие по регулярным выражениям в Python.
Проще говоря, регулярное выражение похоже на сопоставление.
Например, здесь стоят трое толстых мужчин в красной, синей и зеленой одежде.
Правило такое: поймай того, кто в зеленом!
Потом он поймал одного толстого зеленого человека.
Это так просто.
Однако обычная грамматика по-прежнему обширна и глубока, и вы неизбежно будете немного сбиты с толку, когда впервые столкнетесь с ней.
Я всем рекомендую обычный инструмент онлайн-тестирования: онлайн-тестирование с использованием регулярных выражений.
Если регулярность является волшебным оружием, как использовать регулярность в Java?
Давайте сначала посмотрим на простую маленькую сливу.
Ах, не так, маленький каштан.
// Определить шаблон стиля, используя регулярные выражения, а содержимое, которое нужно захватить, находится в круглых скобках
// Это эквивалентно закапыванию ловушки, и если она совпадет, она упадет.
Шаблон шаблона = Pattern.compile("href=/"(.+?)/"");
//Определяем сопоставитель для сопоставления
Matcher matcher = шаблон.matcher("<a href=/"index.html/">Моя домашняя страница</a>");
// если найден
если (matcher.find()) {
// распечатываем результат
System.out.println(matcher.group(1));
}
Результаты запуска:
index.html
Да, это наш первый регулярный код.
Ссылка для получения изображений в этом приложении должна быть у вас под рукой.
Мы инкапсулируем регулярное сопоставление в функцию, а затем модифицируем код следующим образом:
импортировать java.io.*;
импортировать java.net.*;
импортировать java.util.regex.*;
общественный класс Main {
статическая строка SendGet (URL-адрес строки) {
//Определяем строку для хранения содержимого веб-страницы
Строковый результат = "";
//Определяем буферизованный поток ввода символов
BufferedReader в = ноль;
пытаться {
//Преобразуем строку в объект URL
URL-адрес realUrl = новый URL-адрес (url);
// Инициализируем ссылку на этот URL
Соединение URLConnection = realUrl.openConnection();
// Запускаем фактическое соединение
соединение.подключиться();
//Инициализируем входной поток BufferedReader для чтения ответа URL
in = новый BufferedReader (новый InputStreamReader (
Connection.getInputStream()));
// Используется для временного хранения данных каждой захваченной строки
Струнная линия;
while ((line = in.readLine()) != null) {
// Проходим каждую захваченную строку и сохраняем ее в результате
результат += строка;
}
} catch (Исключение е) {
System.out.println("Исключение при отправке запроса GET!" + e);
е.printStackTrace();
}
// Используйте наконец, чтобы закрыть входной поток
окончательно {
пытаться {
если (в != ноль) {
в.закрыть();
}
} catch (Исключение e2) {
e2.printStackTrace();
}
}
вернуть результат;
}
статическая строка RegexString (String targetStr, String PatternStr) {
// Определить шаблон стиля, используя регулярные выражения, а содержимое, которое нужно захватить, находится в круглых скобках
// Это эквивалентно закапыванию ловушки, и если она совпадет, она упадет.
Шаблон шаблона = Pattern.compile(patternStr);
//Определяем сопоставитель для сопоставления
Matcher matcher = шаблон.matcher(targetStr);
// если найден
если (matcher.find()) {
// распечатываем результат
вернуть matcher.group(1);
}
возвращаться "";
}
public static void main(String[] args) {
// Определить ссылку, которую нужно посетить
Строка URL = "http://www.baidu.com";
//Открываем ссылку и получаем содержимое страницы
Строковый результат = SendGet(url);
// Используйте регулярные выражения для сопоставления содержимого src изображения
String imgSrc = RegexString(result, «Предстоящая регулярная грамматика»);
// распечатываем результаты
System.out.println(imgSrc);
}
}
Ладно, теперь все готово, просто обычная грамматика!
Так какое же обычное утверждение более уместно?
Мы обнаружили, что пока мы захватываем строку src="xxxxxx", мы можем получить всю ссылку src.
Итак, простой регулярный оператор: src=/"(.+?)/"
Полный код выглядит следующим образом:
импортировать java.io.*;
импортировать java.net.*;
импортировать java.util.regex.*;
общественный класс Main {
статическая строка SendGet (URL-адрес строки) {
//Определяем строку для хранения содержимого веб-страницы
Строковый результат = "";
//Определяем буферизованный поток ввода символов
BufferedReader в = ноль;
пытаться {
//Преобразуем строку в объект URL
URL-адрес realUrl = новый URL-адрес (url);
// Инициализируем ссылку на этот URL
Соединение URLConnection = realUrl.openConnection();
// Запускаем фактическое соединение
соединение.подключиться();
//Инициализируем входной поток BufferedReader для чтения ответа URL
in = новый BufferedReader (новый InputStreamReader (
Connection.getInputStream()));
// Используется для временного хранения данных каждой захваченной строки
Струнная линия;
while ((line = in.readLine()) != null) {
// Проходим каждую захваченную строку и сохраняем ее в результате
результат += строка;
}
} catch (Исключение е) {
System.out.println("Исключение при отправке запроса GET!" + e);
е.printStackTrace();
}
// Используйте наконец, чтобы закрыть входной поток
окончательно {
пытаться {
если (в != ноль) {
в.закрыть();
}
} catch (Исключение e2) {
e2.printStackTrace();
}
}
вернуть результат;
}
статическая строка RegexString (String targetStr, String PatternStr) {
// Определить шаблон стиля, используя регулярные выражения, а содержимое, которое нужно захватить, находится в круглых скобках
// Это эквивалентно закапыванию ловушки, и если она совпадет, она упадет.
Шаблон шаблона = Pattern.compile(patternStr);
//Определяем сопоставитель для сопоставления
Matcher matcher = шаблон.matcher(targetStr);
// если найден
если (matcher.find()) {
// распечатываем результат
вернуть matcher.group(1);
}
вернуть «Ничего»;
}
public static void main(String[] args) {
// Определить ссылку, которую нужно посетить
Строка URL = "http://www.baidu.com";
//Открываем ссылку и получаем содержимое страницы
Строковый результат = SendGet(url);
// Используйте регулярные выражения для сопоставления содержимого src изображения
String imgSrc = RegexString(result, "src="(.+?)/"");
// распечатываем результаты
System.out.println(imgSrc);
}
}
Таким образом, мы можем использовать Java, чтобы получить ссылку на логотип Baidu.
Что ж, хотя я потратил много времени на разговоры о Baidu, фундамент должен быть заложен прочно. В следующий раз мы официально сосредоточимся на Zhihu! ~