Zhihu — это настоящее онлайн-сообщество вопросов и ответов с дружелюбной, рациональной и серьезной атмосферой, которое объединяет элиту из всех слоев общества. Они делятся друг с другом профессиональными знаниями, опытом и знаниями и постоянно предоставляют высококачественную информацию для китайского Интернета.
Сначала потратьте три-пять минут на разработку логотипа =. =Как программист, я всегда хотел быть художником!
Ладно, это небольшое временное решение, так что я пока с этим справлюсь.
Далее мы приступили к изготовлению гусеницы Чжиху.
Сначала определите первую цель: рекомендацию редактора.
Веб-ссылка: http://www.zhihu.com/explore/recommendations.
Мы немного модифицировали последний код, чтобы сначала добиться возможности получения содержимого страницы:
импортировать 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.zhihu.com/explore/recommendations";
//Открываем ссылку и получаем содержимое страницы
Строковый результат = SendGet(url);
// Используйте регулярные выражения для сопоставления содержимого src изображения
//String imgSrc = RegexString(result, "src="(.+?)/"");
// распечатываем результаты
System.out.println(результат);
}
}
После запуска проблем не возникает. Следующий шаг — это обычная проблема сопоставления.
Для начала давайте ответим на все вопросы на этой странице.
Щелкните правой кнопкой мыши по заголовку и осмотрите элемент:
Ага, вы можете видеть, что заголовок на самом деле является тегом, то есть гиперссылкой, и то, что можно отличить от других гиперссылок, - это класс, который является селектором классов.
Итак, получается наш обычный оператор: questions_link.+?href=/"(.+?)/"
Вызовите функцию RegexString и передайте ей параметры:
public static void main(String[] args) {
// Определить ссылку, которую нужно посетить
Строковый URL = "http://www.zhihu.com/explore/recommendations";
//Открываем ссылку и получаем содержимое страницы
Строковый результат = SendGet(url);
// Используйте регулярные выражения для сопоставления содержимого src изображения
String imgSrc = RegexString(result, "question_link.+?>(.+?)<");
// распечатываем результаты
System.out.println(imgSrc);
}
Ах-ха, вы можете видеть, что мы успешно захватили заголовок (обратите внимание, только один):
Подожди, что это за беспорядок? !
Не нервничай =. = Это просто искаженные символы.
О проблемах с кодировкой см.: Набор символов HTML.
Вообще говоря, основными кодировками с лучшей поддержкой китайского языка являются кодировки UTF-8, GB2312 и GBK.
Веб-страница может установить кодировку веб-страницы с помощью кодировки метатега, например:
<meta charset="utf-8" />
Щелкните правой кнопкой мыши, чтобы просмотреть исходный код страницы:
Как видите, Чжиху использует кодировку UTF-8.
Здесь я объясню вам разницу между просмотром исходного кода страницы и проверкой элементов.
При просмотре исходного кода страницы отображается весь код всей страницы. Он не форматируется в соответствии с HTML-тегами. Этот метод более полезен для просмотра информации всей веб-страницы. мета.
Элемент проверки, или некоторые браузеры называют его элементом просмотра, который предназначен для просмотра элемента, который вы щелкаете правой кнопкой мыши, например div или img. Он больше подходит для просмотра атрибутов и тегов объекта по отдельности.
Хорошо, теперь мы знаем, что проблема кроется в кодировке, следующим шагом будет преобразование кодировки захваченного контента.
Реализация в Java очень проста, достаточно указать метод кодирования в InputStreamReader:
//Инициализируем входной поток BufferedReader для чтения ответа URL
in = новый BufferedReader (новый InputStreamReader (
Connection.getInputStream(),"UTF-8"));
Если вы запустите программу еще раз в это время, вы обнаружите, что заголовок может отображаться нормально:
ХОРОШО! очень хороший!
Но сейчас есть только один заголовок, нам нужны все названия.
Мы немного модифицируем регулярное выражение и сохраним результаты поиска в ArrayList:
импортировать java.io.*;
импортировать java.net.*;
импортировать java.util.ArrayList;
импортировать java.util.regex.*;
общественный класс Main {
статическая строка SendGet (URL-адрес строки) {
//Определяем строку для хранения содержимого веб-страницы
Строковый результат = "";
//Определяем буферизованный поток ввода символов
BufferedReader в = ноль;
пытаться {
//Преобразуем строку в объект URL
URL-адрес realUrl = новый URL-адрес (url);
// Инициализируем ссылку на этот URL
Соединение URLConnection = realUrl.openConnection();
// Запускаем фактическое соединение
соединение.подключиться();
//Инициализируем входной поток BufferedReader для чтения ответа URL
in = новый BufferedReader (новый InputStreamReader (
Connection.getInputStream(), "UTF-8");
// Используется для временного хранения данных каждой захваченной строки
Струнная линия;
while ((line = in.readLine()) != null) {
// Проходим каждую захваченную строку и сохраняем ее в результате
результат += строка;
}
} catch (Исключение е) {
System.out.println("Исключение при отправке запроса GET!" + e);
е.printStackTrace();
}
// Используйте наконец, чтобы закрыть входной поток
окончательно {
пытаться {
если (в != ноль) {
в.закрыть();
}
} catch (Исключение e2) {
e2.printStackTrace();
}
}
вернуть результат;
}
static ArrayList<String> RegexString(String targetStr, String PatternStr) {
// Предварительно определяем ArrayList для хранения результатов
Результаты ArrayList<String> = новый ArrayList<String>();
// Определить шаблон стиля, используя регулярные выражения, а содержимое, которое нужно захватить, находится в круглых скобках
Шаблон шаблона = Pattern.compile(patternStr);
//Определяем сопоставитель для сопоставления
Matcher matcher = шаблон.matcher(targetStr);
// если найден
логическое значение isFind = matcher.find();
// Используйте цикл, чтобы найти и заменить все кельвины в предложении и добавить содержимое в sb
в то время как (isFind) {
//Добавляем успешные результаты сопоставления
results.add(matcher.group(1));
// Продолжаем поиск следующего подходящего объекта
isFind = matcher.find();
}
возврат результатов;
}
public static void main(String[] args) {
// Определить ссылку, которую нужно посетить
Строковый URL = "http://www.zhihu.com/explore/recommendations";
//Открываем ссылку и получаем содержимое страницы
Строковый результат = SendGet(url);
// Используйте регулярные выражения для сопоставления содержимого src изображения
ArrayList<String> imgSrc = RegexString(result, "question_link.+?>(.+?)<");
// распечатываем результаты
System.out.println(imgSrc);
}
}
Это будет соответствовать всем результатам (поскольку ArrayList печатается напрямую, будут квадратные скобки и запятые):
Хорошо, это первый шаг гусеничного робота Zhihu.
Но мы видим, что невозможно охватить все вопросы и ответы таким образом.
Нам нужно разработать класс инкапсуляции Zhihu для хранения всех захваченных объектов.
Исходный код Zhihu.java:
импортировать java.util.ArrayList;
общественный класс Чжиху {
публичная строка вопрос // вопрос;
public String zhihuUrl;//Ссылка на веб-страницу
public ArrayList<String> Answers // Массив для хранения всех ответов;
// Конструктор инициализирует данные
общественный Чжиху () {
вопрос = "";
zhihuUrl = "";
ответы = новый ArrayList<String>();
}
@Override
публичная строка toString() {
return "Вопрос:" + вопрос + "/nLink:" + zhihuUrl + "/nAnswer:" + ответы + "/n";
}
}
Создайте новый класс Spider для хранения некоторых часто используемых функций сканеров.
Исходный код Spider.java:
импортировать java.io.BufferedReader;
импортировать java.io.InputStreamReader;
импортировать java.net.URL;
импортировать java.net.URLConnection;
импортировать java.util.ArrayList;
импортировать java.util.regex.Matcher;
импортировать java.util.regex.Pattern;
общественный класс Паук {
статическая строка SendGet (URL-адрес строки) {
//Определяем строку для хранения содержимого веб-страницы
Строковый результат = "";
//Определяем буферизованный поток ввода символов
BufferedReader в = ноль;
пытаться {
//Преобразуем строку в объект URL
URL-адрес realUrl = новый URL-адрес (url);
// Инициализируем ссылку на этот URL
Соединение URLConnection = realUrl.openConnection();
// Запускаем фактическое соединение
соединение.подключиться();
//Инициализируем входной поток BufferedReader для чтения ответа URL
in = новый BufferedReader (новый InputStreamReader (
Connection.getInputStream(), "UTF-8");
// Используется для временного хранения данных каждой захваченной строки
Струнная линия;
while ((line = in.readLine()) != null) {
// Проходим каждую захваченную строку и сохраняем ее в результате
результат += строка;
}
} catch (Исключение е) {
System.out.println("Исключение при отправке запроса GET!" + e);
е.printStackTrace();
}
// Используйте наконец, чтобы закрыть входной поток
окончательно {
пытаться {
если (в != ноль) {
в.закрыть();
}
} catch (Исключение e2) {
e2.printStackTrace();
}
}
вернуть результат;
}
static ArrayList<Zhihu> GetZhihu(String content) {
// Предварительно определяем ArrayList для хранения результатов
Результаты ArrayList<Zhihu> = новый ArrayList<Zhihu>();
// Используется для сопоставления заголовков
Шаблон вопросаPattern = Pattern.compile("question_link.+?>(.+?)<");
Сопоставитель вопросMatcher = questionsPattern.matcher(content);
// Используется для сопоставления URL-адреса, который является ссылкой на вопрос
Шаблон urlPattern = Pattern.compile("question_link.+?href=/"(.+?)/"");
Сопоставитель urlMatcher = urlPattern.matcher(content);
// И вопрос, и ссылка должны совпадать
логическое значение isFind = questionsMatcher.find() && urlMatcher.find();
в то время как (isFind) {
//Определяем объект Zhihu для хранения захваченной информации
Чжиху zhuhuTemp = новый Чжиху ();
zhuhuTemp.question = questionsMatcher.group(1);
zhuhuTemp.zhihuUrl = "http://www.zhihu.com" + urlMatcher.group(1);
//Добавляем успешные результаты сопоставления
результаты.add(zhuhuTemp);
// Продолжаем поиск следующего подходящего объекта
isFind = вопросMatcher.find() && urlMatcher.find();
}
возврат результатов;
}
}
За вызов отвечает последний основной метод.
импортировать java.util.ArrayList;
общественный класс Main {
public static void main(String[] args) {
// Определить ссылку, которую нужно посетить
Строковый URL = "http://www.zhihu.com/explore/recommendations";
//Открываем ссылку и получаем содержимое страницы
Строковое содержимое = Spider.SendGet(url);
// Получаем все объекты Zhihu на этой странице
ArrayList<Zhihu> myZihu = Spider.GetZhihu(content);
// распечатываем результаты
System.out.println(myZhihu);
}
}
Хорошо, вот и все. Запустите его и посмотрите результаты:
Хорошие результаты.
Следующий шаг — получить доступ к ссылке и получить все ответы.
Мы представим его в следующий раз.
Хорошо, вышеизложенное представляет собой краткое введение во весь процесс использования Java для захвата контента, рекомендованного редакторами Zhihu. Оно очень подробное и легкое для понимания. Друзья, нуждающиеся в помощи, могут свободно обращаться к нему и расширять его. Нет проблем, ха-ха.