Недавно мне нужно заполнить информацию о статье официальной учетной записи WeChat. Я искал онлайн и обнаружил, что сложность ползания общественных аккаунтов WeChat заключается в том, что ссылка на официальную статью учетной записи не может быть открыта на стороне ПК. Мы должны использовать собственный браузер WeChat (вы можете открыть его только на других платформах после того, как вы получите параметры, дополненные клиентом WeChat). Это вызывает большие проблемы для программы Crawler. Позже я увидел официальную программу ползания официальной учетной записи WeChat, написанную большим парнем на Чжиху, и непосредственно последовала за идеей босса и превратил ее в Java. Я столкнулся со многими подробными проблемами во время преобразования, поэтому я поделюсь им.
Основная идея системы состоит в том, чтобы запустить WeChat на эмуляторе Android, настройку прокси для эмулятора, перехватывает данные WeChat через прокси -сервер и отправьте полученные данные в свою собственную программу для обработки.
Среда, которые необходимо подготовиться: Nodejs, AnyProxy Proxy и эмулятор Android
nodejs загружать адрес: http://nodejs.cn/download/. Я скачал версию Windows, просто установите ее напрямую. После установки запуск файлов c:/program/nodejs/npm.cmd автоматически настроит среду.
AnyProxy Installation: после установки NodeJS в соответствии с предыдущим шагом запустите NPM Install -g AnyProxy непосредственно в CMD и установить
Просто зайдите в эмулятор Android онлайн, многие из них.
Во -первых, установите сертификат для прокси -сервера. AnyProxy не разрешает ссылку HTTPS по умолчанию. После установки сертификата его можно разрешить. Выполните AnyProxy -Root в CMD для установки сертификата. После этого вы должны загрузить этот сертификат в эмуляторе.
Затем введите команду AnyProxy -i, чтобы открыть прокси -сервис. (Не забудьте добавить параметры!)
Помните этот IP и порт, а затем агент эмулятора Android будет использовать это. Теперь используйте свой браузер, чтобы открыть веб -страницу: http: // localhost: 8002/Это веб -интерфейс AnyProxy, который используется для отображения данных передачи HTTP.
Нажмите на меню в красном поле выше, и будет выпущен QR -код. Используйте эмулятор Android, чтобы сканировать код, чтобы идентифицировать его. Эмулятор (мобильный телефон) загрузит сертификат и просто установит его.
Теперь вы готовы настроить прокси для эмулятора. Прокси -метод устанавливается в ручное. Прокси IP - это IP, который запускает AnyProxy Machine, а порт 8001
Подготовительная работа в основном завершена здесь. Откройте WeChat на эмуляторе и откройте статью в общедоступной учетной записи, и вы можете увидеть данные, полученные AnyProxy из только что открывшегося веб -интерфейса:
Ссылка на статью WeChat находится в красной коробке выше. Нажмите, чтобы увидеть конкретные данные. Если в корпусе ответа ничего нет, есть проблема с установкой сертификата.
Если все вышеперечисленное сделано, вы можете продолжать идти вниз.
Здесь мы полагаемся на прокси -сервисы для сбора данных WeChat, но мы не можем получить кусок данных и самостоятельно управлять WeChat. Лучше скопировать его вручную. Таким образом, нам нужен клиент WeChat, чтобы самостоятельно прыгнуть на страницу. В настоящее время вы можете использовать AnyProxy для перехвата данных, возвращаемых сервером WeChat, внедрить в него код прыжка страницы, а затем вернуть обработанные данные в симулятор для достижения автоматического прыжка клиента WeChat.
Откройте файл JS с именем rule_default.js в AnyProxy. Файл под Windows: c:/users/administrator/appdata/roaming/npm/node_modules/anyproxy/lib
Существует метод под названием «Заменитель» в файле. Этот метод отвечает за выполнение различных операций по данным, полученным AnyProxy. В начале должен быть только обратный вызов (ServerResdata); Этот оператор означает напрямую возвращать данные ответа сервера в клиенту. Удалите это утверждение напрямую и замените его следующим кодом, написанным Daniu. Я не внес никаких изменений в код здесь, и комментарии в нем объясняются очень четко. Просто прочитайте их напрямую в соответствии с логикой, и нет большой проблемы.
replyserverresdataAsync: function (req, res, serverresdata, обратный вызов) {if (/mp//getmassendmsg/i.test (req.url)) {// Когда адрес ссылки является официальной страницей исторической учетной записи (First Page Form) //console.log("Start на первой странице "); if (serverresdata.tostring ()! == "") {6 try {// предотвратить ошибки от выхода из программы var reg =/msglist = (.*?);/; // определить историческое сообщение регулярное сопоставление var ret = reg.exec (serverresdata.tostring (); // конвертируется с reg.exec (serverresdata.tostring (); Httppost (ret [1], req.url, "/internetspider/getData/showbiz"); // Эта функция определяется позже, отправляя соответствующее историческое сообщение JSON на свой собственный сервер var http = require ('http'); http.get ('http: // xxx/getwxhis', function (res) {// Этот адрес представляет собой программу на собственном сервере. Цель состоит в том, чтобы получить следующий адрес ссылки, поместите адрес в сценарии JS и автоматически перейти на следующую страницу. Callback (chunk+serverresdata); // вставить возвращенный код в историческую страницу сообщения и вернуться, чтобы отобразить его})}); } catch (e) {// Если вышеупомянутое регулярное не совпадает, то содержание этой страницы может быть второй страницей исторического сообщения официальной учетной записи, поскольку первая страница исторического сообщения находится в формате HTML, а вторая страница находится в формате JSON. //console.log("start первая страница ползает вниз по форме "); try {var json = json.parse (serverresdata.tostring ()); if (json.general_msg_list! = []) {httppost (json.general_msg_list, req.url, "/xxx/showbiz"); // Эта функция определяется позже, как указано выше, отправляя JSON во второй странице исторического сообщения на ваш собственный сервер}} Catch (e) {Console.Log (E); Callback (ServerResData); // возвращается непосредственно на содержимое второй страницы json}} //console.log("start первая страница Crawl End "); } else if (/mp//profile_ext/?action=home/i.test (req.url)) {// Когда адрес ссылки является официальной страницей исторической учетной записи (форма второй страницы). reg.exec (serverresdata.toString ()); // конвертировать переменную в строку httppost (ret [1], req.url, "/xxx/showbiz"); // Эта функция определяется позже, отправьте соответствующее историческое сообщение json на свой собственный сервер var http = require ('http'); http.get ('xxx/getwxshis', function (res) {// Этот адрес является программой на вашем сервере. Цель состоит в том, чтобы получить следующий адрес ссылки, поместить адрес в сценарий JS и автоматически перейти на следующую страницу. Принцип getwxhis.php будет введен позже. вернул код на страницу исторического сообщения и вернуться, чтобы отобразить его})}); } catch (e) {//console.log(e); обратный вызов (ServerResdata); }} else if (/mp//profile_ext/?action=getmsg/i.test (req.url)) {// Выражение второй страницы json try {var json = json.parse (serverresdata.tostring ()); if (json.general_msg_list! = []) {httppost (json.general_msg_list, req.url, "/xxx/showbiz"); // Эта функция определяется позже, как указано выше, отправляя JSON во второй странице исторического сообщения своему собственному серверу}} watch (e) {console.log (e); } обратный вызов (ServerResdata); } else if (/mp//getAppmsgext/i.test (req.url)) {// Когда адрес ссылки - это количество просмотров и лайков для официальной статьи учетной записи, Try {httppost (serverresdata, req.url, «/xxx/getmsgext»); // функция определяется позже, и функция прислать json по номеру, а также функция, чтобы отправить json по номеру, и так же, как и функция. сервер} catch (e) {} callback (serverresdata); } else if (/s/? __ biz/i.test (req.url) || /mp//rumor/i.test(Req.Url))K//When Адрес ссылки - официальная статья учетной записи (адрес слуха является официальной статьей учетной записи, она была отклонена) Try {var http = require ('http'); http.get ('http: // xxx/getwxpost', function (res) {// Этот адрес является еще одной программой на вашем сервере. Цель состоит в том, чтобы получить следующий адрес ссылки, поместить адрес в сценарий JS и автоматически перейти на следующую страницу. Callback (Chunk+ServerResdata); } catch (e) {callback (serverresdata); }} else {callback (serverresdata); } // обратный вызов (ServerResdata); },Позвольте мне кратко объяснить здесь, что есть две формы ссылок на историческую страницу сообщений официальных учетных записей WeChat: одна начинается с mp.weixin.qq.com/mp/getmassendmsg, а другой начинается с mp.weixin.qq.com/mp/profile_ext. Страница истории может быть перевернута. Если он перевернет, это запустит событие JS, чтобы отправить запрос на получение данных JSON (содержимое следующей страницы). Существуют также официальные ссылки на статью учетной записи, а также ссылки на количество читаемых и лайков статей (возвращение данных JSON). Формы этих ссылок фиксируются и могут быть выделены логическим суждением. Здесь есть вопрос: как сделать, если все страницы истории должны быть заполнены. Моя идея состоит в том, чтобы моделировать мышь, скользящую через JS, тем самым вызывая запрос на отправку запроса на загрузку следующей части списка. Или напрямую используйте AnyProxy для анализа запроса на скольжение загрузки и напрямую генерировать этот запрос на сервер WeChat. Но есть проблема с тем, как судить, что нет оставшихся данных. Я ползаю по последним данным, и у меня пока нет этого требования, и я могу захотеть этого в будущем. Если вам это нужно, вы можете попробовать.
Следующий рисунок - содержание метода HTTPPOST выше.
Функция httppost (str, url, path) {// отправить JSON на сервер, Str - это контент JSON, URL - это исторический адрес страницы сообщения, путь - это путь и имя файла программы приемной программы
console.log («Начать пересылку»);
пытаться{
var http = require ('http');
var data = {
Str: Encodeuricomponent (str),
URL: Encodeuricomponent (URL)
};
data = require ('QueryString'). stringify (data);
var options = {
Метод: "post",
Хост: «XXX», // Обратите внимание, что нет http: //, это доменное имя сервера.
Порт: xxx,
Путь: Путь, // Путь и имя файла программы принимающей
Заголовки: {
'Content-Type': 'Application/X-WWW-FORM-URLENCODED; charset = utf-8 ',
«Длина контента»: data.length
}
};
var req = http.request (options, function (res) {
res.setEncoding ('utf8');
res.on ('data', function (chunk) {
console.log ('body:' + chunk);
});
});
req.on ('error', function (e) {
console.log («Проблема с запросом: ' + e.message);
});
req.write (data);
req.end ();
} catch (e) {
console.log ("Сообщение об ошибке:"+e);
}
console.log ("Операция пересылки заканчивается");
}После выполнения вышеуказанной работы следующим шагом является завершение кода сервера в соответствии с вашим собственным бизнесом. Наша служба используется для получения данных, отправленных прокси -сервером для обработки, выполнения постоянных операций и в то же время отправить код JS, который необходимо вводить в WeChat на прокси -сервер. Для данных, отправленных по нескольким различным ссылкам, перехваченным прокси -сервером, нам необходимо разработать соответствующие методы для обработки этих данных. Из метода обработки JS AnyProxy для обработки данных WeChat ReploceServerResDataAsync: функция (REQ, RES, ServerResdata, Callback), мы можем знать, что по крайней мере три метода необходимы для разработки данных о странице в истории учетной записи, официальных данных о статье учетной записи, официальных лайков статьи учетной записи и чтения данных. В то же время нам также необходимо разработать метод для создания задач ползания и выполнения ползания официальной учетной записи. Если вам нужно ползти больше данных, вы можете проанализировать более необходимые данные по ссылкам, захваченным AnyProxy, а затем добавить суждение, чтобы заменить замены, перехватывает необходимые данные: Function (REQ, RES, ServerResData, обратный вызов), перехватывает необходимые данные и отправьте их на свой собственный сервер и добавьте соответствующий метод для обработки данных на сервере.
Я пишу код сервера в Java.
Методы обработки официальных данных истории учетной записи:
public void getMsgjson (String Str, String URL) бросает UnsupportedEncodingException {// todo автоматическое сгенерированное метод String biz = ""; "; Map <string, string> querystrs = httpurlparser.parseurl (url); if (querystrs! = null) {biz = Querystrs.get ("__ biz"); biz = biz + "=="; } /*** Запрос из базы данных, существует ли BIZ, и вставьте его, если его не существует. * Это означает, что мы добавили новую официальную учетную запись для цели сбора. */ List <weixin> results = weixinmapper.selectbybiz (biz); if (results == null || result.size () == 0) {weixin weixin = new weixin (); weixin.setbiz (biz); weixin.setCollect (System.CurrentTimeMillis ()); weixinmapper.insert (weixin); } //System.out.println(str); // parse str переменные списки <object> lists = jsonpath.read (str, "['list']"); Для (Список объектов: списки) {Object JSON = List; int type = jsonpath.read (json, "['comm_msg_info'] ['type']"); if (type == 49) {// type = 49 означает, что это строка текстового сообщения content_url = jsonpath.read (json, "$ .app_msg_ext_info.content_url"); content_url = content_url.replace ("//", "") .replaceall ("amp;", ""); // Получить адрес ссылки текстового сообщения int is_multi = jsonpath.read (json, "$ .app_msg_ext_info.is_multi"); // это многочисленное сообщение. "$ .comm_msg_info.dateTime"); // Отправить время изображения и текстового сообщения/** * Здесь адрес и адрес текстовых сообщений вставлен в библиотеку очереди приобретения * (библиотека очереди будет представлена позже. if (content_url! = null &&! "". tmplist.setContenturl (content_url); tmplistmapper.inertselective (tmplist); }} catch (Exception e) {System.out.println ("очередь уже существует, а не вставлен!"); } / *** Здесь мы судим, повторяется ли он из поста базы данных на основе $ content_url* / list <post> postlist = postmapper.selectbycontenturl (content_url); Boolean ContentUrlexist = false; if (postlist! = null && postlist.size ()! = 0) {contentUrlexist = true; } if (! ContentUrlexist) {// 'Тот же $ content_url существует в сообщении базы данных' integer fileId = jsonpath.read (json, "$ .app_msg_ext_info.fileid"); // wechat id title = jsonpath.read (json, "$. = Urlencoder.encode (заголовок, "UTF-8"); String digest = jsonpath.read (json, "$ .App_msg_ext_info.digest"); // Сводка статьи string string_url = jsonpath.read (json, "$ .app_msg_ext_info.source_url"); // Читать оригинальный текстовый ссылка source_url = source_url.re.replace ("//") "); //") String cover = jsonpath.read (json, "$ .app_msg_ext_info.cover"); // Cover Cover = cover.replace ("//", ""); /*** Сохранить в базе данных* /// system.out.println ("title:"+title); // system.out.println ("WeChat Id:"+fileId); // system.out.println ("Сумма из статьи:"+digest); // system.out.println ("Прочтите оригинальный Link:"+Source_url); Адрес: "+Cover); Post = new post (); post.setbiz (biz); post.settitle (заголовок); post.settitleencode (title_encode); post.setfieldid (fileid); post.setDigest (digest); post.setsourceurl (source_url); post.setCover (обложка); post.setistop (1); // пометить его в качестве заголовочного контента post.setismulti (is_multi); post.setDateTime (dateTime); post.setContenturl (content_url); postmapper.insert (post); } if (is_multi == 1) {// Если это мульти-графический список сообщений <object> multilists = jsonpath.read (json, "['app_msg_ext_info'] ['Multi_App_msg_item_list']"); for (Object multilist: multilists) {Object multijson = multilist; content_url = jsonpath.read (multijson, "['' content_url ']"). toString (). Заменить ("//", "") .Replaceall ("amp;", ""); // Графическое сообщение ссылки/** *** Здесь мы будем судить о том, повторяется ли база данных на основе $ content_url, чтобы избежать ошибочных*/content -glextleblebleblebleblebleblebleblebleblebleblebleblebleblebleblebleblebleblebleblebleblebleblebleblebleblebleblebleblebleblebleblebleblebleblebleblebleblebleblebleblebleblebleblebleblebleblebleblebleblebleblebleble. Список <post> post = postmapper.selectbycontenturl (content_url); if (posts! = null && posts.size ()! = 0) {contentUrlexist = true; } if (! ContentUrlexist) {// 'Тот же $ content_url не присутствует в базе данных'/** * Здесь вставьте адрес ссылки на графические и текстовые сообщения в библиотеку очереди приобретения * (библиотека очереди будет введена позже. Основная цель - установить соглашение о приобретении. ! = null &&! ". tmplistt.setcontenturl (content_url); tmplistmapper.inertselective (tmplistt); } String title = jsonpath.read (multijson, "$ .title"); String title_encode = urlencoder.encode (title, "utf-8"); Integer fileId = jsonpath.read (multijson, "$ .fileid"); String digest = jsonpath.read (multijson, "$ .digest"); String source_url = jsonpath.read (multijson, "$ .source_url"); source_url = source_url.replace ("//", ""); String cover = jsonpath.read (multijson, "$ .cover"); cover = cover.replace ("//", ""); // System.out.println ("title:"+title); // System.out.println ("WeChat Id:"+fileId); // System.out.println ("Сводчика:"+digest); // system.out.println ("Читать оригинальный ссылка:"+source_url); // system.out.println ("rehicle:"+source_url); // system.out.println ("reail:"+uppred); Post = new post (); post.setbiz (biz); post.settitle (заголовок); post.settitleencode (title_encode); post.setfieldid (fileid); post.setDigest (digest); post.setsourceurl (source_url); post.setCover (обложка); post.setistop (0); // Tag Это не является заголовочным контентом post.setismulti (is_multi); post.setDateTime (dateTime); post.setContenturl (content_url); postmapper.insert (post); }}}}}}}}}Как иметь дело с официальными страницами статьи учетной записи:
public String getWxpost () {// TODO Auto Generated Method Stub / *** Когда текущая страница является официальной страницей статьи учетной записи, прочитайте эту программу* Сначала удалить Line Load = 1 в списке очерков сбора* затем выберите несколько строк в соответствии с «Порядок ID ASC» от списка доход (обратите внимание, что эта строка отличается от вышеуказанной программы)* / tmplistmapper.delete (1); List <Tmplist> queues = tmplistmapper.selectmany (5); String url = ""; if (queues! = null && queues.size ()! = 0 && queues.size ()> 1) {tmplist queue = queues.get (0); url = queue.getContentUrl (); queue.setisload (1); int result = tmplistmapper.updatebyprimarykey (queue); System.out.println ("Обновление результат:"+result); } else {System.out.println ("getPost queues is null?"+queues == null? null: queues.size ()); Weixin weixin = weixinmapper.selectone (); String biz = weixin.getbiz (); if ((math.random ()> 0.5? 1: 0) == 1) {url = "http://mp.weixin.qq.com/mp/getmasssendmsg?__biz=" + biz + "#wechat_webview_type = 1 & wechat_redirect"; // Разделил = "https://mp.weixin.qq.com/mp/profile_ext?action=home&__biz=" + biz + "#wechat_redirect"; // разделить адрес URL официального исторического сообщения (вторая страница)} url = "https://mp.weixin.qqqquixin.qqqak.commpizehishishishishishishishishishishishishishishishishishishixishixishixishixishixishixishixishixishixiz + biz + "#wechat_redirect"; // разделить адрес URL -адреса официального исторического сообщения (форма второй страницы) // Обновление поля времени сбора в официальной таблице учетных записей, упомянутой только сейчас на текущую марку времени. weixin.setCollect (System.CurrentTimeMillis ()); int result = weixinmapper.updatebyprimarykey (weixin); System.out.println ("getPost weixin updateresult:"+result); } int randomTue = new Random (). NextInt (3) + 3; String jscode = "<script> setTimeout (function () {window.location.href = '"+url+"';},"+randomtime*1000+"); </script>"; вернуть jscode; }Как справиться с количеством лайков и чтений официальных счетов:
public void getMsgext (String Str, String URL) {// TODO автоматически генерируемый метод String biz = ""; String sn = ""; Map <string, string> querystrs = httpurlparser.parseurl (url); if (querystrs! = null) {biz = Querystrs.get ("__ biz"); biz = biz + "=="; sn = querystrs.get ("sn"); sn = "%" + sn + "%"; } /** * $ sql = "select * из таблицы статьи, где` biz` = '". $ biz."' * и `content_url` like '%". $ sn. "%'" Limit 0,1; * Найти соответствующую статью на основе Biz и sn*/ post post = postmapper.selectbybizandsn (biz, sn); if (post == null) {System.out.println ("biz:"+biz); System.out.println ("sn:"+sn); tmplistmapper.deletebyload (1); возвращаться; } // System.out.println ("JSON Data:"+str); Integer read_num; Целое число like_num; try {read_num = jsonpath.read (str, "['appmsgStat'] ['read_num']"); // Читать том как_Нам = jsonpath.read (str, "['appmsgstat'] ['like_num']"); // like gule} catch exception e) {read_num = 123; System.out.println ("read_num:"+read_num); System.out.println ("like_num:"+like_num); System.out.println (e.getMessage ()); } /*** Здесь соответствующая статья также удалена в списке очередей сбора на основе SN, что означает, что эта статья может быть удалена из очереди сбора. * $ sql = "Удалить из` list ', где `content_url` like'%". $ sn. "%'" */ tmplistmapper.deletebysn (sn); // затем обновить количество просмотров и лайков в таблице статьи. post.setreadnum (read_num); post.setLikenum (как_Нем); postmapper.updatebyprimarykey (post); }Как справиться с прыжком в WeChat Incection JS:
public String getWxhis () {string url = ""; // TODO Auto Generated Method Stub /*** Когда текущая страница является историческим сообщением об публичной учетной записи, прочитайте эту программу* В списке очерков сбора есть поле загрузки. Когда значение равно 1, это означает, что оно читается* Сначала удалить Line Load = 1 в списке очередей коллекции* затем выберите любую строку из списка команды*/ tmplistmapper.deleteByload (1); Tmplist queue = tmplistmapper.selectrandomone (); System.out.println ("очередь - это null?"+Queue); if (queue == null) {// Список очередей пуст/*** Если список очередей пуст, получите бизнес из таблицы, хранящий официальный аккаунт. * Здесь я установил поле времени времени сбора в официальной таблице учетных записей. После сортировки в положительном порядке, * Получите запись официальной учетной записи с наименьшей маркой Time и получите свой бизнес */ weixin weixin = weixinmapper.selectone (); String biz = weixin.getbiz (); url = "https://mp.weixin.qq.com/mp/profile_ext?action=home&__biz=" + biz + "#wechat_redirect"; // Разделил официальный исторический адрес сообщений (во второй странице) // Обновление поля времени сбора в официальной таблице учетных записей, упомянутого только на текущий Timestamp. weixin.setCollect (System.CurrentTimeMillis ()); int result = weixinmapper.updatebyprimarykey (weixin); System.out.println ("Gethis weixin updateresult:"+result); } else {// Получить поле content_url текущей строки url = queue.getContenturl (); // Обновление поля загрузки до 1 tmplistmapper.updatebycontenturl (url); } // Измените следующий $ URL, который будет перенаправлен в сценарий JS, и введите его на страницу WeChat AnyProxy. // echo "<script> setTimeout (function () {window.location.href = '". $ url. "';}, 2000); </script>"; int randomtue = new random (). nextint (3) + 3; String jscode = "<script> setTimeout (function () {window.location.href = '"+url+"';},"+randomtime*1000+"); </script>"; вернуть jscode; }Выше приведено программа, которая обрабатывает данные, перехваченные прокси -сервером. Есть проблема, на которую здесь нужно обратить внимание. Программа проведет доступ к каждую официальную учетную запись, включенную в базу данных, и даже сохранившиеся статьи снова будут доступны. Цель состоит в том, чтобы продолжать обновлять количество просмотров и, как статья. Если вам нужно ползти большого количества общественных учетных записей, рекомендуется изменить код для добавления очередей задач и добавления условных ограничений. В противном случае, официальная учетная запись будет ползти по дублированию данных в нескольких раундах, и циклы сильно повлияют на эффективность.
На этом этапе все ссылки на статью официальной учетной записи WeChat были заполнены, и эта ссылка постоянно действительна и может быть открыта в браузере. Затем напишите программу Crawler, чтобы запустить контент статьи и другую информацию из базы данных.
Я густо, написанный на веб -мастереи, он легкий и прост в использовании.
открытый класс Spidermodel реализует PageProcessor {Private Static Postmapper Postmapper; Частный статический список <post> posts; // Соответствующая конфигурация веб -сайта Crawl, включая кодировку, интервал для ползания, время повторной попытки и т. Д. Частный сайт сайта = site.me (). Setretrytimes (3) .setsleeptime (100); public site getsite () {// todo Автогенерированный метод заглушка вернуть это. site; } public void Process (страница страницы) {// TODO Автогенерированный метод заглушка post = posts.remove (0); String content = page.gethtml (). Xpath ("// div [@id = 'js_content']"). Get (); // Статьи Гарри определены здесь. Если есть запись прямого удаления или установить бит представления, чтобы указать, что статья гармонична, если (content == null) {System.out.println («Статья гармонична!»); //postmapper.deletebyprimarykey (post.getid ()); возвращаться; } String contentsNap = content.ReplAceall ("data-src", "src"). Rayalll ("preview.html", "player.html"); // spainshot stringtxttxt = htmltoword.striphtml (content); // conteplectabletextable metacontent = page.gethtml (). xpath ("// div [@id = 'meta_content']"); String pubtime = null; String wxname = null; Строка автор = null; if (metacontent! = null) {pubtime = metacontent.xpath ("// em [@id = 'post-date']"). get (); if (pubtime! = null) {pubtime = htmltoword.striphtml (pubtime); // Время публикации статьи} wxname = metacontent.xpath ("// a [@id = 'post-user']"). get (); if (wxname! = null) {wxname = htmltoword.striphtml (wxname); // public ampoct wome} author = metacontent.xpath ("// em [ @class = 'rich_media_meta rich_media_meta_text' и @id! = 'post-date']"). get (); if (Автор! = null) {Автор = htmltoword.striphtml (Автор); // Автор статьи}} // system.out.println ("Публикация времени:"+pubtime); // system.out.println ("Публичный счет:"+wxname); // System.out.println ("Author Author:"+Автор); String title = post.getTitle (). RyplaceAll ("", ""); // Статья статьи строки digest = post.getDigest (); // Сводка WeChatinfobean (); WeChatbean.SetTitle (заголовок); weChatbean.setContent (contentTxt); // Простой текстовый содержимое wechatbean.setsourcecode (contentsnap); // snapshot wechatbean.setlikecount (likenum); weChatbean.setViewCount (readnum); weChatbean.setabstracttext (digest); // абстрактный wechatbean.seturl (contentUrl); WeChatbean.SetPublishtime (Pubtime); weChatbean.setsiteName (wxName); // имя сайта Общественное имя учетной записи weChatbean.setAuthor (Автор); WeChatbean.SetMediatype ("WeChat Official Account"); // Source Media Type weChatStorage.saveWeChatinfo (WeChatbean); // тег. postmapper.updatebyprimarykey (post); } public static void startSpider (list <post> inposts, postmapper mypostmapper, string ... urls) {long starttime, endtime; startTime = System.CurrentTimeMillis (); postmapper = mypostmapper; Сообщения = Inposts; Httpclientdownloader httpclientdownloader = new httpclientdownloader (); Spidermodel spidermodel = new Spidermodel (); Spider myspider = spider.create (spidermodel) .addurl (urls); myspider.setdownloader (httpclientdownloader); try {spidermonitor.instance (). Register (myspider); myspider.thread (1) .run (); } catch (jmexception e) {e.printstacktrace (); } endtime = System.currentTimeMillis (); System.out.println («Время ползания» + ((endtime-starttime) / 1000) + "секунды-"); }}Я не буду публиковать другие неактуальные коды логики. Здесь я поместил данные, полученные прокси -сервером в MySQL, и хранил данные, заполненные моей программой Crawler в MongoDB.
Ниже приведена информация о официальном номере учетной записи, который вы ползали: