Интеграция MyBatis и Spring для создания краулера: извлечение смешных картинок с Toutiao
Введение в краулер
Toutiao — это платформа, которая сама по себе является краулером. Она собирает информацию об изображениях и текстах с различных сайтов и объединяет её, а затем предоставляет пользователям. Особенно интересны динамические картинки на платформе.
В интернете большинство краулеров написаны на Python, но автор изучает Java Web и не очень хорошо знаком с регулярными выражениями, поэтому он решил попробовать другой подход. В этом краулере используются фреймворки Spring и MyBatis, данные сохраняются в базе данных MySQL, а HTML-теги обрабатываются с помощью Jsoup. Это позволяет избежать использования регулярных выражений.
Краулер извлекает ссылки на динамические изображения из статей и сохраняет их локально, используя заголовки ответов для определения формата изображений. Также можно извлечь текст, например, смешные анекдоты. Этот краулер представляет собой только идею, и есть много других интересных возможностей для разработки.
Выбор технологий
Поиск закономерностей и выделение ключевых моментов
Чтобы понять, как работает краулер, автор изучил запросы Ajax при загрузке страницы. Он обнаружил, что параметры в ответе имеют очевидные значения.
Запрос Ajax содержит три постоянных параметра, которые не меняются. Изменение параметра category позволяет запрашивать разные модули. В данном случае значение равно funny, так как запрос направлен на модуль с забавными картинками. Значения параметров max_behot_time и max_behot_time_tmp представляют собой временные метки. При первом запросе они равны нулю, а в последующих запросах значение max_behot_time_tmp берётся из ответа. Параметры as и cp генерируются с помощью JavaScript и представляют собой зашифрованные временные метки.
Начало работы над фреймворком и написание кода
После создания проекта структура файлов выглядит следующим образом:
Код написан на Java:
package io.z77z.main;
import io.z77z.dao.FunnyMapper;
import io.z77z.entity.Funny;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Date;
import java.util.UUID;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
public class TouTiaoCrawler {
// 搞笑板块的api地址
public static final String FUNNY = "http://www.toutiao.com/api/pc/feed/?utm_source=toutiao&widen=1";
// 头条首页地址
public static final String TOUTIAO = "http://www.toutiao.com";
// 使用"spring.xml"和"spring-mybatis.xml"这两个配置文件创建Spring上下文
static ApplicationContext ac = new ClassPathXmlApplicationContext(
"spring-mybatis.xml");
// 从Spring容器中根据bean的id取出我们要使用的funnyMapper对象
static FunnyMapper funnyMapper = (FunnyMapper) ac.getBean("funnyMapper");
// 接口访问次数
private static int refreshCount = 0;
// 时间戳
private static long time = 0;
public static void main(String[] args) {
System.out.println("----------开始干活!-----------------");
while (true) {
crawler(time);
}
}
public static void crawler(long hottime) {// 传入时间戳,会获取这个时间戳的内容
refreshCount++;
System.out.println("----------第" + refreshCount + "次刷新------返回的请求时间为:"
+ hottime + "----------");
String url = FUNNY + "&max_behot_time=" + hottime
+ "&max_behot_time_tmp=" + hottime;
JSONObject param = getUrlParam(); // 获取用js代码得到的as和cp的值
// 定义接口访问的模块
/*
* __all__ : 推荐 news_hot: 热点 funny:搞笑
*/
String module = "funny";
url += "&as=" + param.get("as") + "&cp=" + param.get("cp")
+ "&category=" + module;
JSONObject json = null;
try {
json = getReturnJson(url);// 获取json串
} catch (Exception e) {
e.printStackTrace();
}
if (json != null) {
time =
Здесь код обрывается. ``` function getParam() { var asas; var cpcp; var t = Math.floor((new Date).getTime() / 1e3), e = t.toString(16).toUpperCase(), i = md5(t).toString().toUpperCase(); if (8 != e.length) { asas = "479BB4B7254C150"; cpcp = "7E0AC8874BB0985"; } else { for (var n = i.slice(0, 5), o = i.slice(-5), a = "", s = 0; 5 > s; s++) { a += n[s] + e[s]; } for (var r = "", c = 0; 5 > c; c++) { r += e[c + 3] + o[c]; } asas = "A1" + a + e.slice(-3); cpcp= e.slice(0, 3) + r + "E1"; } return '{"as":"' + asas + '","cp":"' + cpcp + '"}'; }
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарии ( 0 )