From be25d5569b1a49e30c940174bd8ce5b236becd1a Mon Sep 17 00:00:00 2001 From: fengyuecanzhu <1021300691@qq.com> Date: Sun, 7 Feb 2021 10:50:08 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E4=B9=A6=E6=BA=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 9 +- app/src/main/assets/updatelog.fy | 23 +- .../fycz/myreader/application/SysManager.java | 5 + .../xyz/fycz/myreader/common/APPCONST.java | 2 +- .../xyz/fycz/myreader/enums/BookSource.java | 6 + .../xyz/fycz/myreader/model/SearchEngine.java | 1 + .../myreader/ui/activity/ReadActivity.java | 6 +- .../ui/activity/SearchBookActivity.java | 98 +++++- .../xyz/fycz/myreader/webapi/CommonApi.java | 25 +- .../crawler/read/Ben100ReadCrawler.java | 23 +- .../crawler/read/BiJianReadCrawler.java | 28 +- .../crawler/read/BiQuGe44ReadCrawler.java | 31 +- .../crawler/read/CansShu99ReadCrawler.java | 60 ++-- .../crawler/read/ChuanQiReadCrawler.java | 32 +- .../webapi/crawler/read/DSTQReadCrawler.java | 16 +- .../webapi/crawler/read/Du1DuReadCrawler.java | 30 +- .../crawler/read/EWenXueReadCrawler.java | 151 +++++++++ .../crawler/read/HongChenReadCrawler.java | 68 ++--- .../crawler/read/JiuTaoReadCrawler.java | 48 ++- .../crawler/read/LaoYaoReadCrawler.java | 32 +- .../crawler/read/LiuLangCatReadCrawler.java | 24 +- .../crawler/read/LuoQiuReadCrawler.java | 172 +++++++++++ .../webapi/crawler/read/MiQuReadCrawler.java | 16 +- .../crawler/read/MiaoBiReadCrawler.java | 54 ++-- .../crawler/read/PiaoTianReadCrawler.java | 22 +- .../crawler/read/PinShuReadCrawler.java | 21 +- .../crawler/read/PinShuReadCrawler2.java | 20 +- .../webapi/crawler/read/QB5ReadCrawler.java | 34 ++- .../webapi/crawler/read/QiQiReadCrawler.java | 23 +- .../crawler/read/QuanNovelReadCrawler.java | 24 +- .../webapi/crawler/read/ReXueReadCrawler.java | 32 +- .../crawler/read/ShiGuangReadCrawler.java | 32 +- .../crawler/read/ShuHaiGeReadCrawler.java | 178 +++++++++++ .../crawler/read/SoNovelReadCrawler.java | 24 +- .../crawler/read/TianLaiReadCrawler.java | 29 +- .../crawler/read/WoLongReadCrawler.java | 40 ++- .../crawler/read/XBiQuGeReadCrawler.java | 146 +++++++++ .../webapi/crawler/read/XS7ReadCrawler.java | 50 ++- .../webapi/crawler/read/XS7ReadCrawler2.java | 172 +++++++++++ .../webapi/crawler/read/XiaGuReadCrawler.java | 68 ++--- .../crawler/read/XingXingReadCrawler.java | 48 ++- .../crawler/read/YanQingLouReadCrawler.java | 109 ++++--- .../crawler/read/YunZhongReadCrawler.java | 57 ++-- .../webapi/crawler/read/ZW37ReadCrawler.java | 170 +++++++++++ .../crawler/read/ZaiShuYuanReadCrawler.java | 161 ++++++++++ .../crawler/read/ZuoPinReadCrawler.java | 16 +- .../myreader/widget/page/LocalPageLoader.java | 2 +- .../myreader/widget/page/NetPageLoader.java | 37 ++- .../fycz/myreader/widget/page/PageLoader.java | 108 +++++-- .../main/res/layout/activity_search_book.xml | 286 +++++++++--------- app/src/main/res/menu/menu_search.xml | 6 +- app/src/main/res/values/strings.xml | 7 + app/src/main/resources/crawler.properties | 10 +- app/version_code.properties | 4 +- 54 files changed, 2088 insertions(+), 808 deletions(-) create mode 100644 app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/EWenXueReadCrawler.java create mode 100644 app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/LuoQiuReadCrawler.java create mode 100644 app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/ShuHaiGeReadCrawler.java create mode 100644 app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/XBiQuGeReadCrawler.java create mode 100644 app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/XS7ReadCrawler2.java create mode 100644 app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/ZW37ReadCrawler.java create mode 100644 app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/ZaiShuYuanReadCrawler.java diff --git a/README.md b/README.md index 5d3ab8a..c8f83e5 100644 --- a/README.md +++ b/README.md @@ -2,21 +2,22 @@ 风月读书,一款开源、无广告的小说阅读软件。 -成品下载(v1.8.1):[https://fycz.lanzous.com/i5vu3l6pcuj](https://fycz.lanzous.com/i5vu3l6pcuj) +成品下载(v1.8.2):[https://fycz.lanzous.com/iEy9kldwrpi](https://fycz.lanzous.com/iEy9kldwrpi) [更新日志](./app/src/main/assets/updatelog.fy) #### 一、关于书源 -* 软件内置了~~28~~(25)个书源如下: +* 软件内置了~~36~~(33)个书源如下: - * ~~26~~(23)个网络小说书源:天籁小说、笔趣阁44、~~品书网~~、笔趣阁、 + * ~~32~~(29)个网络小说书源:天籁小说、笔趣阁44、~~品书网~~、笔趣阁、 全本小说、米趣小说、九桃小说、云中书库、 搜小说网、全小说网、~~奇奇小说~~、妙笔阁、 丹书铁券、小说旗、读一读网、飘天文学、 老幺小说、星星小说、时光小说、峡谷文学、 红尘小说、~~热血小说~~、传奇小说、笔尖小说、 - 言情楼、卧龙小说 + 言情楼、卧龙小说、E文学、书海阁、落秋中文、 + 三七中文、新笔趣阁、斋书苑 * 4个实体书书源:超星图书·实体、作品集·实体、99藏书·实体、100本·实体 * 如何自行制作并添加书源. diff --git a/app/src/main/assets/updatelog.fy b/app/src/main/assets/updatelog.fy index 2d9b64e..2db4b8e 100644 --- a/app/src/main/assets/updatelog.fy +++ b/app/src/main/assets/updatelog.fy @@ -1,7 +1,24 @@ -风月读书v1.8.2 +风月读书v1.8.3 1、优化阅读体验 -2、修复已知bug -3、支持分享本地书籍(txt) + +2020.02.06 +风月读书v1.8.2 +更新内容: +1、新增书源:E文学、书海阁、落秋中文、三七中文、新笔趣阁、斋书苑 +2、修复书源:天籁小说、小说旗 +3、优化阅读体验 +4、修复已知bug +5、支持分享本地书籍(txt) + +公告: +2021.02.06: +昨天应该是某站打击盗版导致许多小说网站被墙,书籍无法更新或加载, +您可通过科学上网或换源来获取书籍内容,或者等待网站恢复后更新软件。 + +被墙的书源网站:天籁小说、笔趣阁44、全本小说、米趣小说、九桃小说、 +云中书库、小说旗、老幺小说、传奇小说、星星小说 + +当前已恢复的网站:天籁小说、小说旗(需要更新软件) 2020.02.01 风月读书v1.8.1 diff --git a/app/src/main/java/xyz/fycz/myreader/application/SysManager.java b/app/src/main/java/xyz/fycz/myreader/application/SysManager.java index 207a877..0bbac44 100644 --- a/app/src/main/java/xyz/fycz/myreader/application/SysManager.java +++ b/app/src/main/java/xyz/fycz/myreader/application/SysManager.java @@ -126,6 +126,11 @@ public class SysManager { ReadCrawlerUtil.removeReadCrawler("qiqi", "rexue", "pinshu"); ReadCrawlerUtil.addReadCrawler(BookSource.bijian, BookSource.yanqinglou, BookSource.wolong); Log.d("SourceVersion", "" + 4); + case 5: + ReadCrawlerUtil.addReadCrawler(BookSource.ewenxue, BookSource.shuhaige, + BookSource.luoqiu, BookSource.zw37, BookSource.xbiquge, + BookSource.zaishuyuan); + Log.d("SourceVersion", "" + 5); } setting.setSourceVersion(APPCONST.SOURCE_VERSION); saveSetting(setting); diff --git a/app/src/main/java/xyz/fycz/myreader/common/APPCONST.java b/app/src/main/java/xyz/fycz/myreader/common/APPCONST.java index 5ae4a77..82b5bff 100644 --- a/app/src/main/java/xyz/fycz/myreader/common/APPCONST.java +++ b/app/src/main/java/xyz/fycz/myreader/common/APPCONST.java @@ -83,7 +83,7 @@ public class APPCONST { //设置版本号 public static final int SETTING_VERSION = 11; - public static final int SOURCE_VERSION = 5; + public static final int SOURCE_VERSION = 6; public static final String FORMAT_FILE_DATE = "yyyy-MM-dd"; diff --git a/app/src/main/java/xyz/fycz/myreader/enums/BookSource.java b/app/src/main/java/xyz/fycz/myreader/enums/BookSource.java index 70fe2ed..c45797e 100644 --- a/app/src/main/java/xyz/fycz/myreader/enums/BookSource.java +++ b/app/src/main/java/xyz/fycz/myreader/enums/BookSource.java @@ -37,6 +37,12 @@ public enum BookSource { bijian(MyApplication.getApplication().getString(R.string.read_bijian)), yanqinglou(MyApplication.getApplication().getString(R.string.read_yanqinglou)), wolong(MyApplication.getApplication().getString(R.string.read_wolong)), + ewenxue(MyApplication.getApplication().getString(R.string.read_ewenxue)), + shuhaige(MyApplication.getApplication().getString(R.string.read_shuhaige)), + luoqiu(MyApplication.getApplication().getString(R.string.read_luoqiu)), + zw37(MyApplication.getApplication().getString(R.string.read_zw37)), + xbiquge(MyApplication.getApplication().getString(R.string.read_xbiquge)), + zaishuyuan(MyApplication.getApplication().getString(R.string.read_zaishuyuan)), chaoxing(MyApplication.getApplication().getString(R.string.read_chaoxing)), zuopin(MyApplication.getApplication().getString(R.string.read_zuopin)), cangshu99(MyApplication.getApplication().getString(R.string.read_cangshu99)), diff --git a/app/src/main/java/xyz/fycz/myreader/model/SearchEngine.java b/app/src/main/java/xyz/fycz/myreader/model/SearchEngine.java index a09b378..2b22418 100644 --- a/app/src/main/java/xyz/fycz/myreader/model/SearchEngine.java +++ b/app/src/main/java/xyz/fycz/myreader/model/SearchEngine.java @@ -61,6 +61,7 @@ public class SearchEngine { * 搜索引擎初始化 */ public void initSearchEngine(@NonNull List sourceList) { + mSourceList.clear(); mSourceList.addAll(sourceList); executorService = Executors.newFixedThreadPool(threadsNum); scheduler = Schedulers.from(executorService); diff --git a/app/src/main/java/xyz/fycz/myreader/ui/activity/ReadActivity.java b/app/src/main/java/xyz/fycz/myreader/ui/activity/ReadActivity.java index 98942a9..f572b67 100644 --- a/app/src/main/java/xyz/fycz/myreader/ui/activity/ReadActivity.java +++ b/app/src/main/java/xyz/fycz/myreader/ui/activity/ReadActivity.java @@ -226,7 +226,7 @@ public class ReadActivity extends BaseActivity implements ColorPickerDialogListe break; case 7: ToastUtils.showWarring("无网络连接!"); - mPageLoader.chapterError(); + mPageLoader.chapterError("无网络连接!"); break; case 8: binding.pbLoading.setVisibility(View.GONE); @@ -235,10 +235,6 @@ public class ReadActivity extends BaseActivity implements ColorPickerDialogListe ToastUtils.showInfo("正在后台缓存书籍,具体进度可查看通知栏!"); notificationUtil.requestNotificationPermissionDialog(ReadActivity.this); break; - case 10: - if (mPageLoader != null) { - mPageLoader.chapterError(); - } } } }; diff --git a/app/src/main/java/xyz/fycz/myreader/ui/activity/SearchBookActivity.java b/app/src/main/java/xyz/fycz/myreader/ui/activity/SearchBookActivity.java index e74dc8f..5c2f1a1 100644 --- a/app/src/main/java/xyz/fycz/myreader/ui/activity/SearchBookActivity.java +++ b/app/src/main/java/xyz/fycz/myreader/ui/activity/SearchBookActivity.java @@ -20,6 +20,10 @@ import androidx.appcompat.app.AlertDialog; import androidx.appcompat.widget.Toolbar; import androidx.recyclerview.widget.LinearLayoutManager; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.ArrayList; @@ -28,10 +32,15 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; +import io.reactivex.Single; +import io.reactivex.SingleEmitter; +import io.reactivex.SingleOnSubscribe; +import io.reactivex.annotations.NonNull; import xyz.fycz.myreader.R; import xyz.fycz.myreader.application.MyApplication; import xyz.fycz.myreader.application.SysManager; import xyz.fycz.myreader.base.BaseActivity; +import xyz.fycz.myreader.base.observer.MySingleObserver; import xyz.fycz.myreader.common.APPCONST; import xyz.fycz.myreader.databinding.ActivitySearchBookBinding; import xyz.fycz.myreader.entity.SearchBookBean; @@ -49,6 +58,8 @@ import xyz.fycz.myreader.ui.dialog.MultiChoiceDialog; import xyz.fycz.myreader.util.SharedPreUtils; import xyz.fycz.myreader.util.StringHelper; import xyz.fycz.myreader.util.ToastUtils; +import xyz.fycz.myreader.util.utils.RxUtils; +import xyz.fycz.myreader.webapi.BaseApi; import xyz.fycz.myreader.webapi.CommonApi; import xyz.fycz.myreader.webapi.callback.ResultCallback; import xyz.fycz.myreader.webapi.crawler.ReadCrawlerUtil; @@ -92,6 +103,8 @@ public class SearchBookActivity extends BaseActivity { private static String[] suggestion = {"第一序列", "大道朝天", "伏天氏", "终极斗罗", "我师兄实在太稳健了", "烂柯棋缘", "诡秘之主"}; private static String[] suggestion2 = {"不朽凡人", "圣墟", "我是至尊", "龙王传说", "太古神王", "一念永恒", "雪鹰领主", "大主宰"}; + private boolean showHot; + @SuppressLint("HandlerLeak") private Handler mHandler = new Handler() { @Override @@ -132,8 +145,7 @@ public class SearchBookActivity extends BaseActivity { super.initData(savedInstanceState); mSetting = SysManager.getSetting(); mSearchHistoryService = SearchHistoryService.getInstance(); - Collections.addAll(mSuggestions, suggestion); - + showHot = !MyApplication.isApkInDebug(this); searchEngine = new SearchEngine(); searchEngine.setOnSearchListener(new SearchEngine.OnSearchListener() { @Override @@ -163,9 +175,11 @@ public class SearchBookActivity extends BaseActivity { }); } + @Override protected void initWidget() { super.initWidget(); + initSuggestionList(); binding.etSearchKey.requestFocus();//get the focus //enter事件 binding.etSearchKey.setOnEditorActionListener((textView, i, keyEvent) -> { @@ -238,7 +252,6 @@ public class SearchBookActivity extends BaseActivity { stopSearch(); mHandler.sendMessage(mHandler.obtainMessage(1)); }); - initSuggestionBook(); initHistoryList(); } @@ -247,9 +260,7 @@ public class SearchBookActivity extends BaseActivity { super.initClick(); //换一批点击事件 - binding.renewImage.setOnClickListener(new RenewSuggestionBook()); - //换一批点击事件 - binding.renewText.setOnClickListener(new RenewSuggestionBook()); + binding.llRefreshSuggestBooks.setOnClickListener(new RenewSuggestionBook()); //搜索按钮点击事件 binding.tvSearchConform.setOnClickListener(view -> mHandler.sendMessage(mHandler.obtainMessage(1))); @@ -291,10 +302,19 @@ public class SearchBookActivity extends BaseActivity { return true; } + @Override + public boolean onPrepareOptionsMenu(Menu menu) { + if (!showHot) menu.findItem(R.id.action_hot).setVisible(true); + return super.onPrepareOptionsMenu(menu); + } + @Override public boolean onOptionsItemSelected(MenuItem item) { if (item.getItemId() == R.id.action_disable_source) { showDisableSourceDia(); + }else if (item.getItemId() == R.id.action_hot){ + showHot = !showHot; + initSuggestionList(); } return super.onOptionsItemSelected(item); } @@ -348,18 +368,68 @@ public class SearchBookActivity extends BaseActivity { /** * 初始化建议书目 */ - private void initSuggestionBook() { - binding.tgSuggestBook.setTags(suggestion); + private void initSuggestionList() { + if (!showHot){ + binding.tgSuggestBook.setTags(suggestion); + }else { + SharedPreUtils spu = SharedPreUtils.getInstance(); + String cookie = spu.getString(getString(R.string.qdCookie), ""); + String url = "https://m.qidian.com/majax/search/auto?kw=&"; + if (cookie.equals("")) { + url += "_csrfToken=eXRDlZxmRDLvFAmdgzqvwWAASrxxp2WkVlH4ZM7e"; + } else { + url += cookie.split(";")[0]; + } + BaseApi.getCommonReturnHtmlStringApi(url, null, "utf-8", true, new ResultCallback() { + @Override + public void onFinish(Object o, int code) { + parseSuggestionList((String) o); + if (mSuggestions.size() > 0) { + MyApplication.runOnUiThread(() -> binding.tgSuggestBook.setTags(mSuggestions.subList(0, 5))); + } else { + MyApplication.runOnUiThread(() -> binding.llSuggestBooksView.setVisibility(View.GONE)); + } + } + + @Override + public void onError(Exception e) { + MyApplication.runOnUiThread(() -> binding.llSuggestBooksView.setVisibility(View.GONE)); + } + }); + } + } + + private void parseSuggestionList(String jsonStr) { + try { + JSONObject json = new JSONObject(jsonStr); + JSONArray names = json.getJSONObject("data").getJSONArray("popWords"); + for (int i = 0; i < names.length(); i++) { + mSuggestions.add(names.getJSONObject(i).getString("name")); + } + } catch (JSONException e) { + e.printStackTrace(); + } } private class RenewSuggestionBook implements View.OnClickListener { @Override public void onClick(View v) { - String[] s = binding.tgSuggestBook.getTags(); - if (Arrays.equals(s, suggestion)) { - binding.tgSuggestBook.setTags(suggestion2); - } else { - binding.tgSuggestBook.setTags(suggestion); + if (!showHot) { + String[] s = binding.tgSuggestBook.getTags(); + if (Arrays.equals(s, suggestion)) { + binding.tgSuggestBook.setTags(suggestion2); + } else { + binding.tgSuggestBook.setTags(suggestion); + } + }else { + if (mSuggestions.size() > 0) { + String[] s = binding.tgSuggestBook.getTags(); + if (s[0].equals(mSuggestions.get(0))) { + binding.tgSuggestBook.setTags(mSuggestions.subList(5, 10)); + } else { + binding.tgSuggestBook.setTags(mSuggestions.subList(0, 5)); + } + } } } } @@ -407,7 +477,7 @@ public class SearchBookActivity extends BaseActivity { /*for (ReadCrawler readCrawler : readCrawlers) { searchBookByCrawler(readCrawler, readCrawler.getSearchCharset()); }*/ - searchEngine.initSearchEngine(ReadCrawlerUtil.getReadCrawlers()); + searchEngine.initSearchEngine(readCrawlers); searchEngine.search(searchKey); } diff --git a/app/src/main/java/xyz/fycz/myreader/webapi/CommonApi.java b/app/src/main/java/xyz/fycz/myreader/webapi/CommonApi.java index da1734e..09ad7a5 100644 --- a/app/src/main/java/xyz/fycz/myreader/webapi/CommonApi.java +++ b/app/src/main/java/xyz/fycz/myreader/webapi/CommonApi.java @@ -34,7 +34,7 @@ public class CommonApi extends BaseApi { * @param url * @param callback */ - public static void getBookChapters(String url, final ReadCrawler rc, boolean isRefresh, final ResultCallback callback) { + public static void getBookChapters(String url, final ReadCrawler rc, boolean isRefresh, final ResultCallback callback) { String charset = rc.getCharset(); getCommonReturnHtmlStringApi(url, null, charset, isRefresh, new ResultCallback() { @Override @@ -50,7 +50,6 @@ public class CommonApi extends BaseApi { } - /** * 获取章节列表 * @@ -94,14 +93,7 @@ public class CommonApi extends BaseApi { getCommonReturnHtmlStringApi(url, null, charset, true, new ResultCallback() { @Override public void onFinish(Object o, int code) { - String html = (String) o; - String content = rc.getContentFormHtml(html); - if (rc instanceof YanQingLouReadCrawler && content.contains("正在加载")){ - YanQingLouReadCrawler yrc = (YanQingLouReadCrawler) rc; - yrc.getAjaxContent(html, this); - }else { - callback.onFinish(content, 0); - } + callback.onFinish(rc.getContentFormHtml((String) o), 0); } @Override @@ -173,7 +165,7 @@ public class CommonApi extends BaseApi { String finalCharset = charset; return Observable.create(emitter -> { try { - if (rc.isPost()){ + if (rc.isPost()) { String url = rc.getSearchLink(); String[] urlInfo = url.split(","); url = urlInfo[0]; @@ -181,7 +173,7 @@ public class CommonApi extends BaseApi { MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded"); RequestBody requestBody = RequestBody.create(mediaType, body); emitter.onNext(rc.getBooksFromSearchHtml(OkHttpUtils.getHtml(url, requestBody, finalCharset))); - }else { + } else { emitter.onNext(rc.getBooksFromSearchHtml(OkHttpUtils.getHtml(makeSearchUrl(rc.getSearchLink(), key), finalCharset))); } } catch (Exception e) { @@ -192,7 +184,7 @@ public class CommonApi extends BaseApi { }); } - public static String makeSearchUrl(String url, String key){ + public static String makeSearchUrl(String url, String key) { return url.replace("{key}", key); } @@ -203,9 +195,9 @@ public class CommonApi extends BaseApi { */ public static Observable getBookInfo(final Book book, final BookInfoCrawler bic) { String url; - if (StringHelper.isEmpty(book.getInfoUrl())){ + if (StringHelper.isEmpty(book.getInfoUrl())) { url = book.getChapterUrl(); - }else { + } else { url = book.getInfoUrl(); } return Observable.create(emitter -> { @@ -227,7 +219,7 @@ public class CommonApi extends BaseApi { */ public static void getBookInfo(final Book book, final BookInfoCrawler bic, final ResultCallback callback) { String url = book.getInfoUrl(); - if (StringHelper.isEmpty(url)){ + if (StringHelper.isEmpty(url)) { url = book.getChapterUrl(); } getCommonReturnHtmlStringApi(url, null, bic.getCharset(), false, new ResultCallback() { @@ -256,6 +248,7 @@ public class CommonApi extends BaseApi { public void onFinish(final Object o, int code) { LanZousApi.getKey((String) o, new ResultCallback() { final String referer = (String) o; + @Override public void onFinish(Object o, int code) { LanZousApi.getUrl2((String) o, new ResultCallback() { diff --git a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/Ben100ReadCrawler.java b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/Ben100ReadCrawler.java index daf6df6..9484c4c 100644 --- a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/Ben100ReadCrawler.java +++ b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/Ben100ReadCrawler.java @@ -86,15 +86,11 @@ public class Ben100ReadCrawler extends FindCrawler implements ReadCrawler, BookI public String getContentFormHtml(String html) { Document doc = Jsoup.parse(html); Element divContent = doc.getElementById("content"); - if (divContent != null) { - String content = Html.fromHtml(divContent.html()).toString(); - char c = 160; - String spaec = "" + c; - content = content.replace(spaec, " "); - return content; - } else { - return ""; - } + String content = Html.fromHtml(divContent.html()).toString(); + char c = 160; + String spaec = "" + c; + content = content.replace(spaec, " "); + return content; } /** @@ -199,7 +195,7 @@ public class Ben100ReadCrawler extends FindCrawler implements ReadCrawler, BookI bookType.setTypeName(name); bookType.setUrl(url); bookTypes.add(bookType); - System.out.println("bookTypes.put(\""+ bookType.getTypeName() + "\", \"" + bookType.getUrl() + "\");"); + System.out.println("bookTypes.put(\"" + bookType.getTypeName() + "\", \"" + bookType.getUrl() + "\");"); } return bookTypes; } @@ -208,7 +204,7 @@ public class Ben100ReadCrawler extends FindCrawler implements ReadCrawler, BookI public List getBookTypes() { initBookTypes(); List bookTypes = new ArrayList<>(); - for (String name : mBookTypes.keySet()){ + for (String name : mBookTypes.keySet()) { BookType bookType = new BookType(); bookType.setTypeName(name); bookType.setUrl(mBookTypes.get(name)); @@ -217,7 +213,7 @@ public class Ben100ReadCrawler extends FindCrawler implements ReadCrawler, BookI return bookTypes; } - private void initBookTypes(){ + private void initBookTypes() { mBookTypes.put("世界名著", "https://www.100ben.net/shijiemingzhu/"); mBookTypes.put("现代文学", "https://www.100ben.net/xiandaiwenxue/"); mBookTypes.put("外国小说", "https://www.100ben.net/waiguoxiaoshuo/"); @@ -245,7 +241,8 @@ public class Ben100ReadCrawler extends FindCrawler implements ReadCrawler, BookI String page = pageDiv.getElementsByTag("a").last().text(); String pageStr = page.replace("末页(", "").replace(")", ""); bookType.setPageSize(Integer.parseInt(pageStr)); - } catch (Exception ignored) {} + } catch (Exception ignored) { + } Elements divs = doc.getElementsByClass("recommand"); Element div = divs.get(0); diff --git a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/BiJianReadCrawler.java b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/BiJianReadCrawler.java index 3e763c1..5bdae9d 100644 --- a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/BiJianReadCrawler.java +++ b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/BiJianReadCrawler.java @@ -58,15 +58,11 @@ public class BiJianReadCrawler implements ReadCrawler { public String getContentFormHtml(String html) { Document doc = Jsoup.parse(html); Element divContent = doc.getElementsByClass("read-content").first(); - if (divContent != null) { - String content = Html.fromHtml(divContent.html()).toString(); - char c = 160; - String spaec = "" + c; - content = content.replace(spaec, " "); - return content; - } else { - return ""; - } + String content = Html.fromHtml(divContent.html()).toString(); + char c = 160; + String spaec = "" + c; + content = content.replace(spaec, " "); + return content; } /** @@ -95,13 +91,13 @@ public class BiJianReadCrawler implements ReadCrawler { /** * 从搜索html中得到书列表 - *
  • - * 大主宰:灵玖 - *
    大主宰:灵玖
    - *

    作者:霞露分类:其他连载中

    - *

    简介:她,身负系统,莫名来到了大主宰的时空,成为了聚灵族的最后族人。在她还对周围的情况一片模糊的时候,她遇到了林静这个小恶魔。拜林静所赐,她还遇到了武祖,成为了武柤的小徒弟。参与了灵路,遇到了牧尘和洛璃,她默默的在心中问着自己那一直在划水的系统:“你的活来了,说吧,我该干什么?”

    - * 小说详情 - *
  • + *
  • + * 大主宰:灵玖 + *
    大主宰:灵玖
    + *

    作者:霞露分类:其他连载中

    + *

    简介:她,身负系统,莫名来到了大主宰的时空,成为了聚灵族的最后族人。在她还对周围的情况一片模糊的时候,她遇到了林静这个小恶魔。拜林静所赐,她还遇到了武祖,成为了武柤的小徒弟。参与了灵路,遇到了牧尘和洛璃,她默默的在心中问着自己那一直在划水的系统:“你的活来了,说吧,我该干什么?”

    + * 小说详情 + *
  • */ public ConcurrentMultiValueMap getBooksFromSearchHtml(String html) { ConcurrentMultiValueMap books = new ConcurrentMultiValueMap<>(); diff --git a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/BiQuGe44ReadCrawler.java b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/BiQuGe44ReadCrawler.java index e684d60..1cd63de 100644 --- a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/BiQuGe44ReadCrawler.java +++ b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/BiQuGe44ReadCrawler.java @@ -1,10 +1,12 @@ package xyz.fycz.myreader.webapi.crawler.read; import android.text.Html; + import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; + import xyz.fycz.myreader.entity.SearchBookBean; import xyz.fycz.myreader.enums.BookSource; import xyz.fycz.myreader.greendao.entity.Book; @@ -18,10 +20,12 @@ import java.util.ArrayList; public class BiQuGe44ReadCrawler implements ReadCrawler, BookInfoCrawler { - public static final String NAME_SPACE = "https://www.wqge.cc"; - public static final String NOVEL_SEARCH = "https://www.wqge.cc/modules/article/search.php?searchkey={key}"; + public static final String NAME_SPACE = "http://www.wqge.net"; +// public static final String NAME_SPACE = "https://www.wqge.cc"; + public static final String NOVEL_SEARCH = "http://www.wqge.net/modules/article/search.php?searchkey={key}"; public static final String CHARSET = "GBK"; public static final String SEARCH_CHARSET = "utf-8"; + @Override public String getSearchLink() { return NOVEL_SEARCH; @@ -36,10 +40,12 @@ public class BiQuGe44ReadCrawler implements ReadCrawler, BookInfoCrawler { public String getNameSpace() { return NAME_SPACE; } + @Override public Boolean isPost() { return false; } + @Override public String getSearchCharset() { return SEARCH_CHARSET; @@ -47,21 +53,18 @@ public class BiQuGe44ReadCrawler implements ReadCrawler, BookInfoCrawler { /** * 从html中获取章节正文 + * * @param html * @return */ public String getContentFormHtml(String html) { Document doc = Jsoup.parse(html); Element divContent = doc.getElementById("content"); - if (divContent != null) { - String content = Html.fromHtml(divContent.html()).toString(); - char c = 160; - String spaec = "" + c; - content = content.replace(spaec, " "); - return content; - } else { - return ""; - } + String content = Html.fromHtml(divContent.html()).toString(); + char c = 160; + String spaec = "" + c; + content = content.replace(spaec, " "); + return content; } /** @@ -83,7 +86,7 @@ public class BiQuGe44ReadCrawler implements ReadCrawler, BookInfoCrawler { Elements as = dd.getElementsByTag("a"); if (as.size() > 0) { Element a = as.get(0); - String title = a.text() ; + String title = a.text(); if (!StringHelper.isEmpty(lastTile) && title.equals(lastTile)) { continue; } @@ -101,6 +104,7 @@ public class BiQuGe44ReadCrawler implements ReadCrawler, BookInfoCrawler { /** * 从搜索html中得到书列表 + * * @param html * @return */ @@ -127,9 +131,10 @@ public class BiQuGe44ReadCrawler implements ReadCrawler, BookInfoCrawler { /** * 获取书籍详细信息 + * * @param book */ - public Book getBookInfo(String html, Book book){ + public Book getBookInfo(String html, Book book) { Document doc = Jsoup.parse(html); Element img = doc.getElementById("fmimg"); book.setImgUrl(img.getElementsByTag("img").get(0).attr("src")); diff --git a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/CansShu99ReadCrawler.java b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/CansShu99ReadCrawler.java index dfeba40..bba2e80 100644 --- a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/CansShu99ReadCrawler.java +++ b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/CansShu99ReadCrawler.java @@ -1,10 +1,12 @@ package xyz.fycz.myreader.webapi.crawler.read; import android.text.Html; + import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; + import xyz.fycz.myreader.entity.SearchBookBean; import xyz.fycz.myreader.enums.BookSource; import xyz.fycz.myreader.greendao.entity.Book; @@ -55,15 +57,11 @@ public class CansShu99ReadCrawler implements ReadCrawler { public String getContentFormHtml(String html) { Document doc = Jsoup.parse(html); Element divContent = doc.getElementById("content"); - if (divContent != null) { - String content = Html.fromHtml(divContent.html()).toString(); - char c = 160; - String spaec = "" + c; - content = content.replace(spaec, " "); - return content; - } else { - return ""; - } + String content = Html.fromHtml(divContent.html()).toString(); + char c = 160; + String spaec = "" + c; + content = content.replace(spaec, " "); + return content; } /** @@ -107,28 +105,28 @@ public class CansShu99ReadCrawler implements ReadCrawler { ConcurrentMultiValueMap books = new ConcurrentMultiValueMap<>(); Document doc = Jsoup.parse(html); // try { - Elements divs = doc.getElementsByClass("list_box"); - Element div = divs.get(0); - Elements elementsByTag = div.getElementsByTag("li"); - for (Element element : elementsByTag) { - Book book = new Book(); - String name = element.getElementsByTag("h2").first().getElementsByTag("a").first().text(); - book.setName(name); - String author = element.getElementsByTag("h4").first().getElementsByTag("a").first().text(); - book.setAuthor(author); - String type = element.getElementsByTag("h4").get(1).getElementsByTag("a").text(); - book.setType(type); - String desc = element.getElementsByClass("intro").first().text(); - book.setDesc(desc); - String imgUrl = element.getElementsByTag("img").first().attr("src"); - book.setImgUrl("http:" + imgUrl); - String chapterUrl = element.getElementsByTag("h2").first().getElementsByTag("a").first().attr("href"); - book.setChapterUrl(NAME_SPACE + chapterUrl); - book.setNewestChapterTitle(""); - book.setSource(BookSource.cangshu99.toString()); - SearchBookBean sbb = new SearchBookBean(book.getName(), book.getAuthor()); - books.add(sbb, book); - } + Elements divs = doc.getElementsByClass("list_box"); + Element div = divs.get(0); + Elements elementsByTag = div.getElementsByTag("li"); + for (Element element : elementsByTag) { + Book book = new Book(); + String name = element.getElementsByTag("h2").first().getElementsByTag("a").first().text(); + book.setName(name); + String author = element.getElementsByTag("h4").first().getElementsByTag("a").first().text(); + book.setAuthor(author); + String type = element.getElementsByTag("h4").get(1).getElementsByTag("a").text(); + book.setType(type); + String desc = element.getElementsByClass("intro").first().text(); + book.setDesc(desc); + String imgUrl = element.getElementsByTag("img").first().attr("src"); + book.setImgUrl("http:" + imgUrl); + String chapterUrl = element.getElementsByTag("h2").first().getElementsByTag("a").first().attr("href"); + book.setChapterUrl(NAME_SPACE + chapterUrl); + book.setNewestChapterTitle(""); + book.setSource(BookSource.cangshu99.toString()); + SearchBookBean sbb = new SearchBookBean(book.getName(), book.getAuthor()); + books.add(sbb, book); + } // } catch (Exception e) { // e.printStackTrace(); // } diff --git a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/ChuanQiReadCrawler.java b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/ChuanQiReadCrawler.java index 7cfabb3..5c01570 100644 --- a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/ChuanQiReadCrawler.java +++ b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/ChuanQiReadCrawler.java @@ -58,25 +58,21 @@ public class ChuanQiReadCrawler implements ReadCrawler { public String getContentFormHtml(String html) { Document doc = Jsoup.parse(html); Element divContent = doc.getElementById("txt"); - if (divContent != null) { - Elements aDiv = divContent.getElementsByTag("dd"); - StringBuilder sb = new StringBuilder(); - Collections.sort(aDiv, (o1, o2) -> Integer.parseInt(o1.attr("data-id")) - - Integer.parseInt(o2.attr("data-id"))); - for (int i = 0; i < aDiv.size(); i++) { - Element dd = aDiv.get(i); - if (i == aDiv.size() - 1) break; - sb.append(Html.fromHtml(dd.html()).toString()); - sb.append("\n"); - } - String content = sb.toString(); - char c = 160; - String spaec = "" + c; - content = content.replace(spaec, " "); - return content; - } else { - return ""; + Elements aDiv = divContent.getElementsByTag("dd"); + StringBuilder sb = new StringBuilder(); + Collections.sort(aDiv, (o1, o2) -> Integer.parseInt(o1.attr("data-id")) - + Integer.parseInt(o2.attr("data-id"))); + for (int i = 0; i < aDiv.size(); i++) { + Element dd = aDiv.get(i); + if (i == aDiv.size() - 1) break; + sb.append(Html.fromHtml(dd.html()).toString()); + sb.append("\n"); } + String content = sb.toString(); + char c = 160; + String spaec = "" + c; + content = content.replace(spaec, " "); + return content; } /** diff --git a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/DSTQReadCrawler.java b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/DSTQReadCrawler.java index 92f2863..731fcec 100644 --- a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/DSTQReadCrawler.java +++ b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/DSTQReadCrawler.java @@ -57,15 +57,11 @@ public class DSTQReadCrawler implements ReadCrawler { public String getContentFormHtml(String html) { Document doc = Jsoup.parse(html); Element divContent = doc.getElementById("content"); - if (divContent != null) { - String content = Html.fromHtml(divContent.html()).toString(); - char c = 160; - String spaec = "" + c; - content = content.replace(spaec, " "); - return content; - } else { - return ""; - } + String content = Html.fromHtml(divContent.html()).toString(); + char c = 160; + String spaec = "" + c; + content = content.replace(spaec, " "); + return content; } /** @@ -105,7 +101,7 @@ public class DSTQReadCrawler implements ReadCrawler { try { Element div = doc.getElementsByClass("library").first(); Elements lis = div.getElementsByTag("li"); - for (Element li : lis){ + for (Element li : lis) { Elements as = li.getElementsByTag("a"); Book book = new Book(); book.setName(as.get(1).text()); diff --git a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/Du1DuReadCrawler.java b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/Du1DuReadCrawler.java index e7be199..b866df5 100644 --- a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/Du1DuReadCrawler.java +++ b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/Du1DuReadCrawler.java @@ -27,6 +27,7 @@ public class Du1DuReadCrawler implements ReadCrawler, BookInfoCrawler { public static final String NOVEL_SEARCH = "http://du1du.org/search.htm?keyword={key}"; public static final String CHARSET = "GBK"; public static final String SEARCH_CHARSET = "utf-8"; + @Override public String getSearchLink() { return NOVEL_SEARCH; @@ -41,10 +42,12 @@ public class Du1DuReadCrawler implements ReadCrawler, BookInfoCrawler { public String getNameSpace() { return NAME_SPACE; } + @Override public Boolean isPost() { return false; } + @Override public String getSearchCharset() { return SEARCH_CHARSET; @@ -52,26 +55,23 @@ public class Du1DuReadCrawler implements ReadCrawler, BookInfoCrawler { /** * 从html中获取章节正文 + * * @param html * @return */ public String getContentFormHtml(String html) { Document doc = Jsoup.parse(html); Element divContent = doc.getElementById("txtContent"); - if (divContent != null) { - StringBuilder sb = new StringBuilder(); - for (TextNode textNode : divContent.textNodes()){ - sb.append(textNode.text()); - sb.append("\n"); - } - String content = sb.toString(); - char c = 160; - String spaec = "" + c; - content = content.replace(spaec, " "); - return content; - } else { - return ""; + StringBuilder sb = new StringBuilder(); + for (TextNode textNode : divContent.textNodes()) { + sb.append(textNode.text()); + sb.append("\n"); } + String content = sb.toString(); + char c = 160; + String spaec = "" + c; + content = content.replace(spaec, " "); + return content; } /** @@ -101,6 +101,7 @@ public class Du1DuReadCrawler implements ReadCrawler, BookInfoCrawler { /** * 从搜索html中得到书列表 + * * @param html * @return */ @@ -130,9 +131,10 @@ public class Du1DuReadCrawler implements ReadCrawler, BookInfoCrawler { /** * 获取书籍详细信息 + * * @param book */ - public Book getBookInfo(String html, Book book){ + public Book getBookInfo(String html, Book book) { Document doc = Jsoup.parse(html); Element img = doc.selectFirst("meta[property=og:image]"); book.setImgUrl(img.attr("content")); diff --git a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/EWenXueReadCrawler.java b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/EWenXueReadCrawler.java new file mode 100644 index 0000000..ddd4a73 --- /dev/null +++ b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/EWenXueReadCrawler.java @@ -0,0 +1,151 @@ +package xyz.fycz.myreader.webapi.crawler.read; + +import android.text.Html; + +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.nodes.Element; +import org.jsoup.select.Elements; + +import java.util.ArrayList; + +import xyz.fycz.myreader.entity.SearchBookBean; +import xyz.fycz.myreader.enums.BookSource; +import xyz.fycz.myreader.greendao.entity.Book; +import xyz.fycz.myreader.greendao.entity.Chapter; +import xyz.fycz.myreader.model.mulvalmap.ConcurrentMultiValueMap; +import xyz.fycz.myreader.util.StringHelper; +import xyz.fycz.myreader.webapi.crawler.base.BookInfoCrawler; +import xyz.fycz.myreader.webapi.crawler.base.ReadCrawler; + + +public class EWenXueReadCrawler implements ReadCrawler, BookInfoCrawler { + public static final String NAME_SPACE = "http://ewenxue.org"; + public static final String NOVEL_SEARCH = "http://ewenxue.org/search.htm?keyword={key}"; + public static final String CHARSET = "GBK"; + public static final String SEARCH_CHARSET = "utf-8"; + + @Override + public String getSearchLink() { + return NOVEL_SEARCH; + } + + @Override + public String getCharset() { + return CHARSET; + } + + @Override + public String getNameSpace() { + return NAME_SPACE; + } + + @Override + public Boolean isPost() { + return false; + } + + @Override + public String getSearchCharset() { + return SEARCH_CHARSET; + } + + /** + * 从html中获取章节正文 + * + * @param html + * @return + */ + public String getContentFormHtml(String html) { + Document doc = Jsoup.parse(html); + Element divContent = doc.getElementById("cContent"); + String content = Html.fromHtml(divContent.html()).toString(); + char c = 160; + String spaec = "" + c; + content = content.replace(spaec, " ").replace("setFontSize();", ""); + return content; + } + + /** + * 从html中获取章节列表 + * + * @param html + * @return + */ + public ArrayList getChaptersFromHtml(String html) { + ArrayList chapters = new ArrayList<>(); + Document doc = Jsoup.parse(html); + String readUrl = NAME_SPACE + doc.select(".breadcrumb").first() + .select("a").last().attr("href"); + Element divList = doc.getElementById("chapters-list"); + String lastTile = null; + int i = 0; + Elements elementsByTag = divList.getElementsByTag("a"); + for (int j = 0; j < elementsByTag.size(); j++) { + Element a = elementsByTag.get(j); + String title = a.text(); + if (!StringHelper.isEmpty(lastTile) && title.equals(lastTile)) { + continue; + } + Chapter chapter = new Chapter(); + chapter.setNumber(i++); + chapter.setTitle(title); + String url = readUrl + a.attr("href"); + chapter.setUrl(url); + chapters.add(chapter); + lastTile = title; + } + return chapters; + } + + /** + * 从搜索html中得到书列表 + * + * @param html + * @return
  • + *
    玄幻
    + * + * + *
    天蚕土豆
    + *
    2019-07-05 16:03
    + *
  • + */ + public ConcurrentMultiValueMap getBooksFromSearchHtml(String html) { + ConcurrentMultiValueMap books = new ConcurrentMultiValueMap<>(); + Document doc = Jsoup.parse(html); + Elements elements = doc.getElementsByClass("clearfix"); + for (int i = 1; i < elements.size(); i++) { + Element element = elements.get(i); + Book book = new Book(); + Elements info = element.getElementsByTag("div"); + book.setName(info.get(1).text()); + book.setInfoUrl(NAME_SPACE + info.get(1).getElementsByTag("a").attr("href")); + book.setChapterUrl(book.getInfoUrl() + "mulu.htm"); + book.setAuthor(info.get(3).text()); + book.setNewestChapterTitle(info.get(2).text()); + book.setType(info.get(0).text()); + book.setSource(BookSource.ewenxue.toString()); + SearchBookBean sbb = new SearchBookBean(book.getName(), book.getAuthor()); + books.add(sbb, book); + } + return books; + } + + /** + * 获取书籍详细信息 + * + * @param book + */ + public Book getBookInfo(String html, Book book) { + Document doc = Jsoup.parse(html); + Element img = doc.getElementsByClass("img-thumbnail").first(); + book.setImgUrl(img.attr("src")); + Element desc = doc.getElementById("all"); + if (desc == null) { + desc = doc.getElementById("shot"); + } + book.setDesc(desc.text().replace("[收起]", "")); + return book; + } + +} diff --git a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/HongChenReadCrawler.java b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/HongChenReadCrawler.java index a8dc5ec..6a8ea8b 100644 --- a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/HongChenReadCrawler.java +++ b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/HongChenReadCrawler.java @@ -58,25 +58,21 @@ public class HongChenReadCrawler implements ReadCrawler { public String getContentFormHtml(String html) { Document doc = Jsoup.parse(html); Element divContent = doc.getElementById("txt"); - if (divContent != null) { - Elements aDiv = divContent.getElementsByTag("dd"); - StringBuilder sb = new StringBuilder(); - Collections.sort(aDiv, (o1, o2) -> Integer.parseInt(o1.attr("data-id")) - - Integer.parseInt(o2.attr("data-id"))); - for (int i = 0; i < aDiv.size(); i++) { - Element dd = aDiv.get(i); - if (i == aDiv.size() - 1) break; - sb.append(Html.fromHtml(dd.html()).toString()); - sb.append("\n"); - } - String content = sb.toString(); - char c = 160; - String spaec = "" + c; - content = content.replace(spaec, " "); - return content; - } else { - return ""; + Elements aDiv = divContent.getElementsByTag("dd"); + StringBuilder sb = new StringBuilder(); + Collections.sort(aDiv, (o1, o2) -> Integer.parseInt(o1.attr("data-id")) - + Integer.parseInt(o2.attr("data-id"))); + for (int i = 0; i < aDiv.size(); i++) { + Element dd = aDiv.get(i); + if (i == aDiv.size() - 1) break; + sb.append(Html.fromHtml(dd.html()).toString()); + sb.append("\n"); } + String content = sb.toString(); + char c = 160; + String spaec = "" + c; + content = content.replace(spaec, " "); + return content; } /** @@ -130,24 +126,24 @@ public class HongChenReadCrawler implements ReadCrawler { ConcurrentMultiValueMap books = new ConcurrentMultiValueMap<>(); Document doc = Jsoup.parse(html); // try { - Element div = doc.getElementsByClass("s-b-list").first(); - Elements dls = div.getElementsByTag("dl"); - for (Element dl : dls){ - Elements as = dl.getElementsByTag("a"); - Book book = new Book(); - book.setName(as.get(1).text()); - book.setAuthor(as.get(2).text()); - book.setType(as.get(3).text()); - book.setNewestChapterTitle(as.get(4).text().replace("最近更新 ", "")); - book.setDesc(dl.getElementsByClass("big-book-info").first().text()); - String imgUrl = dl.getElementsByTag("img").attr("data-original"); - book.setImgUrl(imgUrl); - //https://www.zuxs.net/zu/1140.html -> https://www.zuxs.net/zu/1/1140/ - book.setChapterUrl(NAME_SPACE + as.get(1).attr("href").replace("zu/", "zu/1/").replace(".html", "/")); - book.setSource(BookSource.hongchen.toString()); - SearchBookBean sbb = new SearchBookBean(book.getName(), book.getAuthor()); - books.add(sbb, book); - } + Element div = doc.getElementsByClass("s-b-list").first(); + Elements dls = div.getElementsByTag("dl"); + for (Element dl : dls) { + Elements as = dl.getElementsByTag("a"); + Book book = new Book(); + book.setName(as.get(1).text()); + book.setAuthor(as.get(2).text()); + book.setType(as.get(3).text()); + book.setNewestChapterTitle(as.get(4).text().replace("最近更新 ", "")); + book.setDesc(dl.getElementsByClass("big-book-info").first().text()); + String imgUrl = dl.getElementsByTag("img").attr("data-original"); + book.setImgUrl(imgUrl); + //https://www.zuxs.net/zu/1140.html -> https://www.zuxs.net/zu/1/1140/ + book.setChapterUrl(NAME_SPACE + as.get(1).attr("href").replace("zu/", "zu/1/").replace(".html", "/")); + book.setSource(BookSource.hongchen.toString()); + SearchBookBean sbb = new SearchBookBean(book.getName(), book.getAuthor()); + books.add(sbb, book); + } // } catch (Exception e) { // e.printStackTrace(); // } diff --git a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/JiuTaoReadCrawler.java b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/JiuTaoReadCrawler.java index 8b99a55..049e4e6 100644 --- a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/JiuTaoReadCrawler.java +++ b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/JiuTaoReadCrawler.java @@ -1,10 +1,12 @@ package xyz.fycz.myreader.webapi.crawler.read; import android.text.Html; + import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; + import xyz.fycz.myreader.entity.SearchBookBean; import xyz.fycz.myreader.enums.BookSource; import xyz.fycz.myreader.greendao.entity.Book; @@ -55,15 +57,11 @@ public class JiuTaoReadCrawler implements ReadCrawler { public String getContentFormHtml(String html) { Document doc = Jsoup.parse(html); Element divContent = doc.getElementById("content"); - if (divContent != null) { - String content = Html.fromHtml(divContent.html()).toString(); - char c = 160; - String spaec = "" + c; - content = content.replace(spaec, " ").replaceAll("您可以在.*最新章节!|\\\\", ""); - return content; - } else { - return ""; - } + String content = Html.fromHtml(divContent.html()).toString(); + char c = 160; + String spaec = "" + c; + content = content.replace(spaec, " ").replaceAll("您可以在.*最新章节!|\\\\", ""); + return content; } /** @@ -101,22 +99,22 @@ public class JiuTaoReadCrawler implements ReadCrawler { ConcurrentMultiValueMap books = new ConcurrentMultiValueMap<>(); Document doc = Jsoup.parse(html); // try { - Element div = doc.getElementsByClass("library").first(); - Elements lis = div.getElementsByTag("li"); - for (Element li : lis){ - Elements as = li.getElementsByTag("a"); - Book book = new Book(); - book.setName(as.get(1).text()); - book.setAuthor(as.get(2).text()); - book.setType(as.get(3).text()); - book.setNewestChapterTitle(as.get(4).text().replace("最新章节:", "")); - book.setDesc(li.getElementsByClass("intro").first().text()); - book.setImgUrl(li.getElementsByTag("img").attr("src")); - book.setChapterUrl(NAME_SPACE + as.get(1).attr("href").replace(".html", "/")); - book.setSource(BookSource.jiutao.toString()); - SearchBookBean sbb = new SearchBookBean(book.getName(), book.getAuthor()); - books.add(sbb, book); - } + Element div = doc.getElementsByClass("library").first(); + Elements lis = div.getElementsByTag("li"); + for (Element li : lis) { + Elements as = li.getElementsByTag("a"); + Book book = new Book(); + book.setName(as.get(1).text()); + book.setAuthor(as.get(2).text()); + book.setType(as.get(3).text()); + book.setNewestChapterTitle(as.get(4).text().replace("最新章节:", "")); + book.setDesc(li.getElementsByClass("intro").first().text()); + book.setImgUrl(li.getElementsByTag("img").attr("src")); + book.setChapterUrl(NAME_SPACE + as.get(1).attr("href").replace(".html", "/")); + book.setSource(BookSource.jiutao.toString()); + SearchBookBean sbb = new SearchBookBean(book.getName(), book.getAuthor()); + books.add(sbb, book); + } // } catch (Exception e) { // e.printStackTrace(); // } diff --git a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/LaoYaoReadCrawler.java b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/LaoYaoReadCrawler.java index 4c454b7..7d7170f 100644 --- a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/LaoYaoReadCrawler.java +++ b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/LaoYaoReadCrawler.java @@ -61,25 +61,21 @@ public class LaoYaoReadCrawler implements ReadCrawler { public String getContentFormHtml(String html) { Document doc = Jsoup.parse(html); Element divContent = doc.getElementById("txt"); - if (divContent != null) { - Elements aDiv = divContent.getElementsByTag("dd"); - StringBuilder sb = new StringBuilder(); - Collections.sort(aDiv, (o1, o2) -> Integer.parseInt(o1.attr("data-id")) - - Integer.parseInt(o2.attr("data-id"))); - for (int i = 0; i < aDiv.size(); i++) { - Element dd = aDiv.get(i); - if (i == aDiv.size() - 1) break; - sb.append(Html.fromHtml(dd.html()).toString()); - sb.append("\n"); - } - String content = sb.toString(); - char c = 160; - String spaec = "" + c; - content = content.replace(spaec, " "); - return content; - } else { - return ""; + Elements aDiv = divContent.getElementsByTag("dd"); + StringBuilder sb = new StringBuilder(); + Collections.sort(aDiv, (o1, o2) -> Integer.parseInt(o1.attr("data-id")) - + Integer.parseInt(o2.attr("data-id"))); + for (int i = 0; i < aDiv.size(); i++) { + Element dd = aDiv.get(i); + if (i == aDiv.size() - 1) break; + sb.append(Html.fromHtml(dd.html()).toString()); + sb.append("\n"); } + String content = sb.toString(); + char c = 160; + String spaec = "" + c; + content = content.replace(spaec, " "); + return content; } /** diff --git a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/LiuLangCatReadCrawler.java b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/LiuLangCatReadCrawler.java index 5867b76..0ea6afc 100644 --- a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/LiuLangCatReadCrawler.java +++ b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/LiuLangCatReadCrawler.java @@ -26,8 +26,8 @@ import xyz.fycz.myreader.webapi.crawler.base.ReadCrawler; */ public class LiuLangCatReadCrawler implements ReadCrawler { public static final String NAME_SPACE = "http://m.liulangcat.com"; - public static final String NOVEL_SEARCH = "http://m.liulangcat.com/get/get_search_result.php?page=0&keyword={key}"; -// public static final String NOVEL_SEARCH = "http://www.liulangcat.com/search.php?k={key}&submit=搜索&wgxojg=wc0yz&uwzgzw=yi1p7&amlmvy=mcp50&rybwbm=1s0y7"; + public static final String NOVEL_SEARCH = "http://m.liulangcat.com/get/get_search_result.php?page=0&keyword={key}"; + // public static final String NOVEL_SEARCH = "http://www.liulangcat.com/search.php?k={key}&submit=搜索&wgxojg=wc0yz&uwzgzw=yi1p7&amlmvy=mcp50&rybwbm=1s0y7"; public static final String CHARSET = "utf-8"; public static final String SEARCH_CHARSET = "utf-8"; @@ -154,17 +154,13 @@ public class LiuLangCatReadCrawler implements ReadCrawler { Document doc = Jsoup.parse(html); Element divContent = doc.getElementsByClass("item_content").first(); Element nameSpan = doc.getElementsByClass("top_categoryname").first(); - if (divContent != null) { - String content = Html.fromHtml(divContent.html()).toString(); - char c = 160; - String spaec = "" + c; - content = content.replace(spaec, " "). - replace(nameSpan.text(), ""). - replace("主页", ""). - replace("目录", ""); - return content; - } else { - return ""; - } + String content = Html.fromHtml(divContent.html()).toString(); + char c = 160; + String spaec = "" + c; + content = content.replace(spaec, " "). + replace(nameSpan.text(), ""). + replace("主页", ""). + replace("目录", ""); + return content; } } diff --git a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/LuoQiuReadCrawler.java b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/LuoQiuReadCrawler.java new file mode 100644 index 0000000..90cd9a7 --- /dev/null +++ b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/LuoQiuReadCrawler.java @@ -0,0 +1,172 @@ +package xyz.fycz.myreader.webapi.crawler.read; + +import android.text.Html; + +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.nodes.Element; +import org.jsoup.select.Elements; + +import java.util.ArrayList; + +import xyz.fycz.myreader.entity.SearchBookBean; +import xyz.fycz.myreader.enums.BookSource; +import xyz.fycz.myreader.greendao.entity.Book; +import xyz.fycz.myreader.greendao.entity.Chapter; +import xyz.fycz.myreader.model.mulvalmap.ConcurrentMultiValueMap; +import xyz.fycz.myreader.util.StringHelper; +import xyz.fycz.myreader.webapi.crawler.base.BookInfoCrawler; +import xyz.fycz.myreader.webapi.crawler.base.ReadCrawler; + + +public class LuoQiuReadCrawler implements ReadCrawler, BookInfoCrawler { + public static final String NAME_SPACE = "https://www.lqbook.com"; + public static final String NOVEL_SEARCH = "https://www.lqbook.com/modules/article/search.php?searchkey={key}&submit=%CB%D1%CB%F7"; + public static final String CHARSET = "GBK"; + public static final String SEARCH_CHARSET = "GBK"; + + @Override + public String getSearchLink() { + return NOVEL_SEARCH; + } + + @Override + public String getCharset() { + return CHARSET; + } + + @Override + public String getNameSpace() { + return NAME_SPACE; + } + + @Override + public Boolean isPost() { + return false; + } + + @Override + public String getSearchCharset() { + return SEARCH_CHARSET; + } + + /** + * 从html中获取章节正文 + * + * @param html + * @return + */ + public String getContentFormHtml(String html) { + Document doc = Jsoup.parse(html); + Element divContent = doc.getElementById("content"); + String content = Html.fromHtml(divContent.html()).toString(); + char c = 160; + String spaec = "" + c; + content = content.replace(spaec, " ") + .replaceAll("^.*最新章节!", ""); + return content; + } + + /** + * 从html中获取章节列表 + * + * @param html + * @return + */ + public ArrayList getChaptersFromHtml(String html) { + ArrayList chapters = new ArrayList<>(); + Document doc = Jsoup.parse(html); + String readUrl = doc.select("meta[property=og:novel:read_url]").attr("content"); + Element divList = doc.selectFirst(".zjlist"); + String lastTile = null; + int i = 0; + Elements elementsByTag = divList.getElementsByTag("a"); + for (int j = 0; j < elementsByTag.size(); j++) { + Element a = elementsByTag.get(j); + String title = a.text(); + if (!StringHelper.isEmpty(lastTile) && title.equals(lastTile)) { + continue; + } + Chapter chapter = new Chapter(); + chapter.setNumber(i++); + chapter.setTitle(title); + String url = readUrl + a.attr("href"); + chapter.setUrl(url); + chapters.add(chapter); + lastTile = title; + } + return chapters; + } + + /** + * 从搜索html中得到书列表 + * + * @param html + * @return + * 文娱大主宰 + * 很抱歉,是时候结束了。 + * 羽林都督 + * 480K + * 20-10-02 + * 连载 + * + */ + public ConcurrentMultiValueMap getBooksFromSearchHtml(String html) { + ConcurrentMultiValueMap books = new ConcurrentMultiValueMap<>(); + Document doc = Jsoup.parse(html); + String urlType = doc.select("meta[property=og:type]").attr("content"); + if ("novel".equals(urlType)) { + String readUrl = doc.select("meta[property=og:novel:read_url]").attr("content"); + Book book = new Book(); + book.setChapterUrl(readUrl); + getBookInfo(html, book); + SearchBookBean sbb = new SearchBookBean(book.getName(), book.getAuthor()); + books.add(sbb, book); + } else { + Element div = doc.getElementById("main"); + Elements elements = div.getElementsByTag("tr"); + for (int i = 1; i < elements.size(); i++) { + Element element = elements.get(i); + Book book = new Book(); + Elements info = element.getElementsByTag("td"); + book.setName(info.get(0).text()); + book.setChapterUrl(info.get(0).selectFirst("a").attr("href")); + book.setAuthor(info.get(2).text()); + book.setNewestChapterTitle(info.get(1).text()); + book.setSource(BookSource.luoqiu.toString()); + SearchBookBean sbb = new SearchBookBean(book.getName(), book.getAuthor()); + books.add(sbb, book); + } + } + return books; + } + + /** + * 获取书籍详细信息 + * + * @param book + */ + public Book getBookInfo(String html, Book book) { + Document doc = Jsoup.parse(html); + book.setSource(BookSource.luoqiu.toString()); + + String name = doc.select("meta[property=og:title]").attr("content"); + book.setName(name); + String url = doc.select("meta[property=og:novel:read_url]").attr("content"); + book.setChapterUrl(url); + String author = doc.select("meta[property=og:novel:author]").attr("content"); + book.setAuthor(author); + String newestChapter = doc.select("meta[property=og:novel:latest_chapter_name]").attr("content"); + book.setNewestChapterTitle(newestChapter); + + Element img = doc.getElementById("picbox"); + book.setImgUrl(img.getElementsByTag("img").get(0).attr("src")); + Element desc = doc.getElementById("intro"); + book.setDesc(Html.fromHtml(desc.html()).toString()); + //类型 + String type = doc.select("meta[property=og:novel:category]").attr("content"); + book.setType(type); + return book; + } + +} diff --git a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/MiQuReadCrawler.java b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/MiQuReadCrawler.java index f0705e5..37f4c0d 100644 --- a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/MiQuReadCrawler.java +++ b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/MiQuReadCrawler.java @@ -1,10 +1,12 @@ package xyz.fycz.myreader.webapi.crawler.read; import android.text.Html; + import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; + import xyz.fycz.myreader.entity.SearchBookBean; import xyz.fycz.myreader.enums.BookSource; import xyz.fycz.myreader.greendao.entity.Book; @@ -56,15 +58,11 @@ public class MiQuReadCrawler implements ReadCrawler, BookInfoCrawler { public String getContentFormHtml(String html) { Document doc = Jsoup.parse(html); Element divContent = doc.getElementById("content"); - if (divContent != null) { - String content = Html.fromHtml(divContent.html()).toString(); - char c = 160; - String spaec = "" + c; - content = content.replace(spaec, " ").replace("applyChapterSetting();", ""); - return content; - } else { - return ""; - } + String content = Html.fromHtml(divContent.html()).toString(); + char c = 160; + String spaec = "" + c; + content = content.replace(spaec, " ").replace("applyChapterSetting();", ""); + return content; } /** diff --git a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/MiaoBiReadCrawler.java b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/MiaoBiReadCrawler.java index 9e86eb3..4e44244 100644 --- a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/MiaoBiReadCrawler.java +++ b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/MiaoBiReadCrawler.java @@ -83,15 +83,11 @@ public class MiaoBiReadCrawler extends FindCrawler implements ReadCrawler { public String getContentFormHtml(String html) { Document doc = Jsoup.parse(html); Element divContent = doc.getElementById("content"); - if (divContent != null) { - String content = Html.fromHtml(divContent.html()).toString(); - char c = 160; - String spaec = "" + c; - content = content.replace(spaec, " ").replaceAll("您可以在.*最新章节!|\\\\", ""); - return content; - } else { - return ""; - } + String content = Html.fromHtml(divContent.html()).toString(); + char c = 160; + String spaec = "" + c; + content = content.replace(spaec, " ").replaceAll("您可以在.*最新章节!|\\\\", ""); + return content; } /** @@ -129,22 +125,22 @@ public class MiaoBiReadCrawler extends FindCrawler implements ReadCrawler { ConcurrentMultiValueMap books = new ConcurrentMultiValueMap<>(); Document doc = Jsoup.parse(html); // try { - Element div = doc.getElementById("sitembox"); - Elements dls = div.getElementsByTag("dl"); - for (Element dl : dls){ - Elements as = dl.getElementsByTag("a"); - Book book = new Book(); - book.setName(as.get(1).text()); - book.setAuthor(as.get(3).text()); - book.setType(as.get(2).text()); - book.setNewestChapterTitle(as.get(4).text()); - book.setDesc(dl.getElementsByClass("book_des").first().text()); - book.setImgUrl(as.first().getElementsByTag("img").attr("src")); - book.setChapterUrl(NAME_SPACE + as.get(1).attr("href").replace("novel", "read").replace(".html", "/")); - book.setSource(BookSource.miaobi.toString()); - SearchBookBean sbb = new SearchBookBean(book.getName(), book.getAuthor()); - books.add(sbb, book); - } + Element div = doc.getElementById("sitembox"); + Elements dls = div.getElementsByTag("dl"); + for (Element dl : dls) { + Elements as = dl.getElementsByTag("a"); + Book book = new Book(); + book.setName(as.get(1).text()); + book.setAuthor(as.get(3).text()); + book.setType(as.get(2).text()); + book.setNewestChapterTitle(as.get(4).text()); + book.setDesc(dl.getElementsByClass("book_des").first().text()); + book.setImgUrl(as.first().getElementsByTag("img").attr("src")); + book.setChapterUrl(NAME_SPACE + as.get(1).attr("href").replace("novel", "read").replace(".html", "/")); + book.setSource(BookSource.miaobi.toString()); + SearchBookBean sbb = new SearchBookBean(book.getName(), book.getAuthor()); + books.add(sbb, book); + } // } catch (Exception e) { // e.printStackTrace(); // } @@ -155,7 +151,7 @@ public class MiaoBiReadCrawler extends FindCrawler implements ReadCrawler { public List getBookTypes() { initBookTypes(); List bookTypes = new ArrayList<>(); - for (String name : mBookTypes.keySet()){ + for (String name : mBookTypes.keySet()) { BookType bookType = new BookType(); bookType.setTypeName(name); bookType.setUrl(mBookTypes.get(name)); @@ -165,7 +161,7 @@ public class MiaoBiReadCrawler extends FindCrawler implements ReadCrawler { return bookTypes; } - private void initBookTypes(){ + private void initBookTypes() { mBookTypes.put("玄幻奇幻", "https://www.imiaobige.com/xuanhuan/1.html"); mBookTypes.put("武侠仙侠", "https://www.imiaobige.com/wuxia/1.html"); mBookTypes.put("都市生活", "https://www.imiaobige.com/dushi/1.html"); @@ -189,7 +185,7 @@ public class MiaoBiReadCrawler extends FindCrawler implements ReadCrawler { Document doc = Jsoup.parse(html); Element div = doc.getElementById("sitebox"); Elements dls = div.getElementsByTag("dl"); - for (Element dl : dls){ + for (Element dl : dls) { Book book = new Book(); Elements as = dl.getElementsByTag("a"); book.setName(as.get(1).text()); @@ -208,7 +204,7 @@ public class MiaoBiReadCrawler extends FindCrawler implements ReadCrawler { @Override public boolean getTypePage(BookType curType, int page) { - if (page > curType.getPageSize()){ + if (page > curType.getPageSize()) { return true; } curType.setUrl(curType.getUrl().substring(0, curType.getUrl().lastIndexOf("/") + 1) + page + ".html"); diff --git a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/PiaoTianReadCrawler.java b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/PiaoTianReadCrawler.java index ca2f1bb..ba7c3f2 100644 --- a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/PiaoTianReadCrawler.java +++ b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/PiaoTianReadCrawler.java @@ -23,6 +23,7 @@ public class PiaoTianReadCrawler implements ReadCrawler, BookInfoCrawler { public static final String NOVEL_SEARCH = "https://www.piaotian.org/modules/article/search.php?searchkey={key}&submit=%CB%D1%CB%F7"; public static final String CHARSET = "GBK"; public static final String SEARCH_CHARSET = "GBK"; + @Override public String getSearchLink() { return NOVEL_SEARCH; @@ -37,10 +38,12 @@ public class PiaoTianReadCrawler implements ReadCrawler, BookInfoCrawler { public String getNameSpace() { return NAME_SPACE; } + @Override public Boolean isPost() { return false; } + @Override public String getSearchCharset() { return SEARCH_CHARSET; @@ -48,21 +51,18 @@ public class PiaoTianReadCrawler implements ReadCrawler, BookInfoCrawler { /** * 从html中获取章节正文 + * * @param html * @return */ public String getContentFormHtml(String html) { Document doc = Jsoup.parse(html); Element divContent = doc.getElementById("htmlContent"); - if (divContent != null) { - String content = Html.fromHtml(divContent.html()).toString(); - char c = 160; - String spaec = "" + c; - content = content.replace(spaec, " ").replaceAll("飘天文学.*最新章节!", ""); - return content; - } else { - return ""; - } + String content = Html.fromHtml(divContent.html()).toString(); + char c = 160; + String spaec = "" + c; + content = content.replace(spaec, " ").replaceAll("飘天文学.*最新章节!", ""); + return content; } /** @@ -93,6 +93,7 @@ public class PiaoTianReadCrawler implements ReadCrawler, BookInfoCrawler { /** * 从搜索html中得到书列表 + * * @param html * @return */ @@ -132,9 +133,10 @@ public class PiaoTianReadCrawler implements ReadCrawler, BookInfoCrawler { /** * 获取书籍详细信息 + * * @param book */ - public Book getBookInfo(String html, Book book){ + public Book getBookInfo(String html, Book book) { Document doc = Jsoup.parse(html); Element name = doc.selectFirst("meta[property=og:novel:book_name]"); book.setName(name.attr("content")); diff --git a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/PinShuReadCrawler.java b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/PinShuReadCrawler.java index bb34efe..1b912eb 100644 --- a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/PinShuReadCrawler.java +++ b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/PinShuReadCrawler.java @@ -1,10 +1,12 @@ package xyz.fycz.myreader.webapi.crawler.read; import android.text.Html; + import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; + import xyz.fycz.myreader.entity.SearchBookBean; import xyz.fycz.myreader.enums.BookSource; import xyz.fycz.myreader.greendao.entity.Book; @@ -42,14 +44,17 @@ public class PinShuReadCrawler implements ReadCrawler, BookInfoCrawler { public String getNameSpace() { return NAME_SPACE; } + @Override public Boolean isPost() { return false; } + @Override public String getSearchCharset() { return SEARCH_CHARSET; } + /** * 从html中获取章节正文 * @@ -59,16 +64,12 @@ public class PinShuReadCrawler implements ReadCrawler, BookInfoCrawler { public String getContentFormHtml(String html) { Document doc = Jsoup.parse(html); Element divContent = doc.getElementById("BookText"); - if (divContent != null) { - String content = Html.fromHtml(divContent.html()).toString(); - char c = 160; - String spaec = "" + c; - content = content.replace(spaec, " ").replace("品书网", "") - .replace("手机阅读", ""); - return StringHelper.IgnoreCaseReplace(content, "www.vodtw.com", ""); - } else { - return ""; - } + String content = Html.fromHtml(divContent.html()).toString(); + char c = 160; + String spaec = "" + c; + content = content.replace(spaec, " ").replace("品书网", "") + .replace("手机阅读", ""); + return StringHelper.IgnoreCaseReplace(content, "www.vodtw.com", ""); } /** diff --git a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/PinShuReadCrawler2.java b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/PinShuReadCrawler2.java index f128787..6eedfd8 100644 --- a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/PinShuReadCrawler2.java +++ b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/PinShuReadCrawler2.java @@ -1,10 +1,12 @@ package xyz.fycz.myreader.webapi.crawler.read; import android.text.Html; + import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; + import xyz.fycz.myreader.entity.SearchBookBean; import xyz.fycz.myreader.enums.BookSource; import xyz.fycz.myreader.greendao.entity.Book; @@ -41,10 +43,12 @@ public class PinShuReadCrawler2 implements ReadCrawler, BookInfoCrawler { public String getNameSpace() { return NAME_SPACE; } + @Override public Boolean isPost() { return false; } + @Override public String getSearchCharset() { return SEARCH_CHARSET; @@ -59,16 +63,12 @@ public class PinShuReadCrawler2 implements ReadCrawler, BookInfoCrawler { public String getContentFormHtml(String html) { Document doc = Jsoup.parse(html); Element divContent = doc.getElementById("BookText"); - if (divContent != null) { - String content = Html.fromHtml(divContent.html()).toString(); - char c = 160; - String spaec = "" + c; - content = content.replace(spaec, " ").replace("品书网", "") - .replace("手机阅读", ""); - return StringHelper.IgnoreCaseReplace(content, "www.vodtw.com", ""); - } else { - return ""; - } + String content = Html.fromHtml(divContent.html()).toString(); + char c = 160; + String spaec = "" + c; + content = content.replace(spaec, " ").replace("品书网", "") + .replace("手机阅读", ""); + return StringHelper.IgnoreCaseReplace(content, "www.vodtw.com", ""); } /** diff --git a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/QB5ReadCrawler.java b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/QB5ReadCrawler.java index cec3359..4cb7cbf 100644 --- a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/QB5ReadCrawler.java +++ b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/QB5ReadCrawler.java @@ -1,10 +1,12 @@ package xyz.fycz.myreader.webapi.crawler.read; import android.text.Html; + import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; + import xyz.fycz.myreader.entity.SearchBookBean; import xyz.fycz.myreader.entity.bookstore.BookType; import xyz.fycz.myreader.enums.BookSource; @@ -37,10 +39,12 @@ public class QB5ReadCrawler extends FindCrawler implements ReadCrawler, BookInfo public String getNameSpace() { return NAME_SPACE; } + @Override public Boolean isPost() { return false; } + @Override public String getCharset() { return CHARSET; @@ -89,7 +93,8 @@ public class QB5ReadCrawler extends FindCrawler implements ReadCrawler, BookInfo BookType bookType = new BookType(); bookType.setTypeName(a.attr("title")); bookType.setUrl(a.attr("href")); - if (bookType.getTypeName().contains("首页") || bookType.getTypeName().contains("热门小说")) continue; + if (bookType.getTypeName().contains("首页") || bookType.getTypeName().contains("热门小说")) + continue; if (!StringHelper.isEmpty(bookType.getTypeName())) { bookTypes.add(bookType); } @@ -138,7 +143,8 @@ public class QB5ReadCrawler extends FindCrawler implements ReadCrawler, BookInfo try { int pageSize = Integer.parseInt(doc.getElementsByClass("last").first().text()); bookType.setPageSize(pageSize); - }catch (Exception ignored){} + } catch (Exception ignored) { + } String type = doc.select("meta[name=keywords]").attr("content").replace(",全本小说网", ""); Element div = doc.getElementById("tlist"); Elements uls = div.getElementsByTag("ul"); @@ -170,16 +176,12 @@ public class QB5ReadCrawler extends FindCrawler implements ReadCrawler, BookInfo Element divBook = doc.getElementsByClass("nav-style").get(0); String bookName = divBook.getElementsByTag("a").get(1).attr("title"); Element divContent = doc.getElementById("content"); - if (divContent != null) { - String content = Html.fromHtml(divContent.html()).toString(); - char c = 160; - String spaec = "" + c; - content = content.replace(spaec, " "); - content = content.replaceAll("全本小说.*最新章节!", ""); - return content; - } else { - return ""; - } + String content = Html.fromHtml(divContent.html()).toString(); + char c = 160; + String spaec = "" + c; + content = content.replace(spaec, " "); + content = content.replaceAll("全本小说.*最新章节!", ""); + return content; } @@ -276,16 +278,16 @@ public class QB5ReadCrawler extends FindCrawler implements ReadCrawler, BookInfo } - public boolean getTypePage(BookType curType, int page){ - if (curType.getPageSize() <= 0){ + public boolean getTypePage(BookType curType, int page) { + if (curType.getPageSize() <= 0) { curType.setPageSize(10); } - if (page > curType.getPageSize()){ + if (page > curType.getPageSize()) { return true; } if (!curType.getTypeName().equals("完本小说")) { curType.setUrl(curType.getUrl().substring(0, curType.getUrl().lastIndexOf("_") + 1) + page + "/"); - }else { + } else { curType.setUrl(curType.getUrl().substring(0, curType.getUrl().lastIndexOf("/") + 1) + page); } return false; diff --git a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/QiQiReadCrawler.java b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/QiQiReadCrawler.java index 62acb9e..f0b55c4 100644 --- a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/QiQiReadCrawler.java +++ b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/QiQiReadCrawler.java @@ -5,6 +5,7 @@ import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.nodes.TextNode; import org.jsoup.select.Elements; + import xyz.fycz.myreader.entity.SearchBookBean; import xyz.fycz.myreader.enums.BookSource; import xyz.fycz.myreader.greendao.entity.Book; @@ -59,20 +60,16 @@ public class QiQiReadCrawler implements ReadCrawler { public String getContentFormHtml(String html) { Document doc = Jsoup.parse(html); Element divContent = doc.getElementById("content"); - if (divContent != null) { - StringBuilder sb = new StringBuilder(); - for (TextNode textNode : divContent.textNodes()){ - sb.append(textNode.text()); - sb.append("\n"); - } - String content = sb.toString(); - char c = 160; - String spaec = "" + c; - content = content.replace(spaec, " ").replaceAll("奇奇小说全网.*com|更新最.*com\\\\/|哽噺.*com|www.*com\"", ""); - return content; - } else { - return ""; + StringBuilder sb = new StringBuilder(); + for (TextNode textNode : divContent.textNodes()) { + sb.append(textNode.text()); + sb.append("\n"); } + String content = sb.toString(); + char c = 160; + String spaec = "" + c; + content = content.replace(spaec, " ").replaceAll("奇奇小说全网.*com|更新最.*com\\\\/|哽噺.*com|www.*com\"", ""); + return content; } /** diff --git a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/QuanNovelReadCrawler.java b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/QuanNovelReadCrawler.java index 137ad85..62764e2 100644 --- a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/QuanNovelReadCrawler.java +++ b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/QuanNovelReadCrawler.java @@ -1,11 +1,13 @@ package xyz.fycz.myreader.webapi.crawler.read; import android.text.Html; + import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.nodes.TextNode; import org.jsoup.select.Elements; + import xyz.fycz.myreader.entity.SearchBookBean; import xyz.fycz.myreader.enums.BookSource; import xyz.fycz.myreader.greendao.entity.Book; @@ -57,20 +59,16 @@ public class QuanNovelReadCrawler implements ReadCrawler, BookInfoCrawler { public String getContentFormHtml(String html) { Document doc = Jsoup.parse(html); Element divContent = doc.getElementById("content"); - if (divContent != null) { - StringBuilder sb = new StringBuilder(); - for (TextNode textNode : divContent.textNodes()){ - sb.append(textNode.text()); - sb.append("\n"); - } - String content = sb.toString(); - char c = 160; - String spaec = "" + c; - content = content.replace(spaec, " ").replaceAll("\\s*您可以.*最.*章节.*", ""); - return content; - } else { - return ""; + StringBuilder sb = new StringBuilder(); + for (TextNode textNode : divContent.textNodes()) { + sb.append(textNode.text()); + sb.append("\n"); } + String content = sb.toString(); + char c = 160; + String spaec = "" + c; + content = content.replace(spaec, " ").replaceAll("\\s*您可以.*最.*章节.*", ""); + return content; } /** diff --git a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/ReXueReadCrawler.java b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/ReXueReadCrawler.java index 53b1138..c675ff7 100644 --- a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/ReXueReadCrawler.java +++ b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/ReXueReadCrawler.java @@ -61,25 +61,21 @@ public class ReXueReadCrawler implements ReadCrawler { public String getContentFormHtml(String html) { Document doc = Jsoup.parse(html); Element divContent = doc.getElementById("txt"); - if (divContent != null) { - Elements aDiv = divContent.getElementsByTag("dd"); - StringBuilder sb = new StringBuilder(); - Collections.sort(aDiv, (o1, o2) -> Integer.parseInt(o1.attr("data-id")) - - Integer.parseInt(o2.attr("data-id"))); - for (int i = 0; i < aDiv.size(); i++) { - Element dd = aDiv.get(i); - if (i == aDiv.size() - 1) break; - sb.append(Html.fromHtml(dd.html()).toString()); - sb.append("\n"); - } - String content = sb.toString(); - char c = 160; - String spaec = "" + c; - content = content.replace(spaec, " "); - return content; - } else { - return ""; + Elements aDiv = divContent.getElementsByTag("dd"); + StringBuilder sb = new StringBuilder(); + Collections.sort(aDiv, (o1, o2) -> Integer.parseInt(o1.attr("data-id")) - + Integer.parseInt(o2.attr("data-id"))); + for (int i = 0; i < aDiv.size(); i++) { + Element dd = aDiv.get(i); + if (i == aDiv.size() - 1) break; + sb.append(Html.fromHtml(dd.html()).toString()); + sb.append("\n"); } + String content = sb.toString(); + char c = 160; + String spaec = "" + c; + content = content.replace(spaec, " "); + return content; } /** diff --git a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/ShiGuangReadCrawler.java b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/ShiGuangReadCrawler.java index 0ea4ce6..84a10d8 100644 --- a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/ShiGuangReadCrawler.java +++ b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/ShiGuangReadCrawler.java @@ -58,25 +58,21 @@ public class ShiGuangReadCrawler implements ReadCrawler { public String getContentFormHtml(String html) { Document doc = Jsoup.parse(html); Element divContent = doc.getElementById("txt"); - if (divContent != null) { - Elements aDiv = divContent.getElementsByTag("dd"); - StringBuilder sb = new StringBuilder(); - Collections.sort(aDiv, (o1, o2) -> Integer.parseInt(o1.attr("data-id")) - - Integer.parseInt(o2.attr("data-id"))); - for (int i = 0; i < aDiv.size(); i++) { - Element dd = aDiv.get(i); - if (i == aDiv.size() - 1) break; - sb.append(Html.fromHtml(dd.html()).toString()); - sb.append("\n"); - } - String content = sb.toString(); - char c = 160; - String spaec = "" + c; - content = content.replace(spaec, " "); - return content; - } else { - return ""; + Elements aDiv = divContent.getElementsByTag("dd"); + StringBuilder sb = new StringBuilder(); + Collections.sort(aDiv, (o1, o2) -> Integer.parseInt(o1.attr("data-id")) - + Integer.parseInt(o2.attr("data-id"))); + for (int i = 0; i < aDiv.size(); i++) { + Element dd = aDiv.get(i); + if (i == aDiv.size() - 1) break; + sb.append(Html.fromHtml(dd.html()).toString()); + sb.append("\n"); } + String content = sb.toString(); + char c = 160; + String spaec = "" + c; + content = content.replace(spaec, " "); + return content; } /** diff --git a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/ShuHaiGeReadCrawler.java b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/ShuHaiGeReadCrawler.java new file mode 100644 index 0000000..3f6bc81 --- /dev/null +++ b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/ShuHaiGeReadCrawler.java @@ -0,0 +1,178 @@ +package xyz.fycz.myreader.webapi.crawler.read; + +import android.text.Html; + +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.nodes.Element; +import org.jsoup.nodes.TextNode; +import org.jsoup.select.Elements; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import xyz.fycz.myreader.entity.SearchBookBean; +import xyz.fycz.myreader.enums.BookSource; +import xyz.fycz.myreader.greendao.entity.Book; +import xyz.fycz.myreader.greendao.entity.Chapter; +import xyz.fycz.myreader.model.mulvalmap.ConcurrentMultiValueMap; +import xyz.fycz.myreader.util.StringHelper; +import xyz.fycz.myreader.util.utils.OkHttpUtils; +import xyz.fycz.myreader.webapi.crawler.base.BookInfoCrawler; +import xyz.fycz.myreader.webapi.crawler.base.ReadCrawler; + + +public class ShuHaiGeReadCrawler implements ReadCrawler, BookInfoCrawler { + public static final String NAME_SPACE = "https://www.xinshuhaige.net"; + public static final String NOVEL_SEARCH = "https://www.xinshuhaige.net/search.html,searchkey={key}&searchtype=all"; + public static final String CHARSET = "utf-8"; + public static final String SEARCH_CHARSET = "utf-8"; + + @Override + public String getSearchLink() { + return NOVEL_SEARCH; + } + + @Override + public String getCharset() { + return CHARSET; + } + + @Override + public String getNameSpace() { + return NAME_SPACE; + } + + @Override + public Boolean isPost() { + return true; + } + + @Override + public String getSearchCharset() { + return SEARCH_CHARSET; + } + + /** + * 从html中获取章节正文 + * + * @param html + * @return + */ + public String getContentFormHtml(String html) { + Document doc = Jsoup.parse(html); + Element divContent = doc.getElementsByClass("content").first(); + StringBuilder sb = new StringBuilder(); + List textNodes = divContent.textNodes(); + for (int i = 1; i < textNodes.size() - 6; i++) { + TextNode textNode = textNodes.get(i); + sb.append(textNode.text()); + sb.append("\n"); + } + String content = sb.toString(); + char c = 160; + String spaec = "" + c; + content = content.replace(spaec, " "); + return content; + } + + /** + * 从html中获取章节列表 + * + * @param html + * @return + */ + public ArrayList getChaptersFromHtml(String html) { + ArrayList chapters = new ArrayList<>(); + Document doc = Jsoup.parse(html); + Element divList = doc.getElementsByClass("novel_list").last(); + String lastTile = null; + int i = 0; + Elements elementsByTag = divList.getElementsByTag("a"); + for (int j = 0; j < elementsByTag.size(); j++) { + Element a = elementsByTag.get(j); + String title = a.text(); + if (!StringHelper.isEmpty(lastTile) && title.equals(lastTile)) { + continue; + } + Chapter chapter = new Chapter(); + chapter.setNumber(i++); + chapter.setTitle(title); + String url = NAME_SPACE + a.attr("href"); + chapter.setUrl(url); + chapters.add(chapter); + lastTile = title; + } + try { + Element pages = doc.getElementById("pagelink"); + if (pages != null) { + String nextPageUrl = ""; + Element nextPage = doc.selectFirst(".caption") + .selectFirst("a"); + if ("下一页".equals(nextPage.text())) { + nextPageUrl = NAME_SPACE + nextPage.attr("href"); + } + if (!StringHelper.isEmpty(nextPageUrl)) { + List nextChapters = getChaptersFromHtml(OkHttpUtils.getHtml(nextPageUrl, CHARSET)); + for (Chapter nextChapter : nextChapters) { + nextChapter.setNumber(chapters.size()); + chapters.add(nextChapter); + } + } + } + } catch (IOException e) { + e.printStackTrace(); + } + return chapters; + } + + /** + * 从搜索html中得到书列表 + * + * @param html + * @return
  • + * [都市生活] + * 都市大主宰 + * 第1462章  相似 + * 赌霸 + * 2021-02-05 + * 连载 + *
  • + */ + public ConcurrentMultiValueMap getBooksFromSearchHtml(String html) { + ConcurrentMultiValueMap books = new ConcurrentMultiValueMap<>(); + Document doc = Jsoup.parse(html); + Element div = doc.getElementsByClass("novelslist2").first(); + Elements elements = div.getElementsByTag("li"); + for (int i = 1; i < elements.size(); i++) { + Element element = elements.get(i); + Book book = new Book(); + Elements info = element.getElementsByTag("span"); + book.setName(info.get(1).text()); + book.setChapterUrl(NAME_SPACE + info.get(1).getElementsByTag("a").attr("href")); + book.setAuthor(info.get(3).text()); + book.setNewestChapterTitle(info.get(2).text()); + book.setType(info.get(0).getElementsByTag("a").first().text()); + book.setSource(BookSource.shuhaige.toString()); + SearchBookBean sbb = new SearchBookBean(book.getName(), book.getAuthor()); + books.add(sbb, book); + } + return books; + } + + /** + * 获取书籍详细信息 + * + * @param book + */ + public Book getBookInfo(String html, Book book) { + Document doc = Jsoup.parse(html); + String img = doc.select("meta[property=og:image]").attr("content"); + book.setImgUrl(img); + String desc = doc.select("meta[property=og:description]").attr("content"); + book.setDesc(desc.replaceAll("新书海阁.*观看小说:", "")); + return book; + } + +} diff --git a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/SoNovelReadCrawler.java b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/SoNovelReadCrawler.java index be76f5d..a3e8bed 100644 --- a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/SoNovelReadCrawler.java +++ b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/SoNovelReadCrawler.java @@ -1,11 +1,13 @@ package xyz.fycz.myreader.webapi.crawler.read; import android.text.Html; + import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.nodes.TextNode; import org.jsoup.select.Elements; + import xyz.fycz.myreader.entity.SearchBookBean; import xyz.fycz.myreader.enums.BookSource; import xyz.fycz.myreader.greendao.entity.Book; @@ -58,20 +60,16 @@ public class SoNovelReadCrawler implements ReadCrawler, BookInfoCrawler { public String getContentFormHtml(String html) { Document doc = Jsoup.parse(html); Element divContent = doc.getElementsByClass("content").first(); - if (divContent != null) { - StringBuilder sb = new StringBuilder(); - for (TextNode textNode : divContent.textNodes()){ - sb.append(textNode.text()); - sb.append("\n"); - } - String content = sb.toString(); - char c = 160; - String spaec = "" + c; - content = content.replace(spaec, " ").replaceAll("\\s*您可以.*最.*章节.*", ""); - return content; - } else { - return ""; + StringBuilder sb = new StringBuilder(); + for (TextNode textNode : divContent.textNodes()) { + sb.append(textNode.text()); + sb.append("\n"); } + String content = sb.toString(); + char c = 160; + String spaec = "" + c; + content = content.replace(spaec, " ").replaceAll("\\s*您可以.*最.*章节.*", ""); + return content; } /** diff --git a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/TianLaiReadCrawler.java b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/TianLaiReadCrawler.java index 326021e..9ad1e37 100644 --- a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/TianLaiReadCrawler.java +++ b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/TianLaiReadCrawler.java @@ -6,6 +6,7 @@ import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; + import xyz.fycz.myreader.entity.SearchBookBean; import xyz.fycz.myreader.enums.BookSource; import xyz.fycz.myreader.greendao.entity.Book; @@ -21,8 +22,9 @@ import java.util.ArrayList; */ public class TianLaiReadCrawler implements ReadCrawler { - public static final String NAME_SPACE = "https://www.23txt.com"; - public static final String NOVEL_SEARCH = "https://www.23txt.com/search.php?q={key}"; + // public static final String NAME_SPACE = "https://www.23txt.com"; + public static final String NAME_SPACE = "https://www.233txt.com"; + public static final String NOVEL_SEARCH = "https://www.233txt.com/search.php?q={key}"; public static final String CHARSET = "GBK"; public static final String SEARCH_CHARSET = "utf-8"; @@ -30,6 +32,7 @@ public class TianLaiReadCrawler implements ReadCrawler { public String getSearchLink() { return NOVEL_SEARCH; } + @Override public String getCharset() { return CHARSET; @@ -39,10 +42,12 @@ public class TianLaiReadCrawler implements ReadCrawler { public String getNameSpace() { return NAME_SPACE; } + @Override public Boolean isPost() { return false; } + @Override public String getSearchCharset() { return SEARCH_CHARSET; @@ -57,16 +62,12 @@ public class TianLaiReadCrawler implements ReadCrawler { public String getContentFormHtml(String html) { Document doc = Jsoup.parse(html); Element divContent = doc.getElementById("content"); - if (divContent != null) { - String content = Html.fromHtml(divContent.html()).toString(); - char c = 160; - String spaec = "" + c; - content = content.replace(spaec, " "); - content = content.replaceAll("笔趣阁.*最新章节!", ""); - return content; - } else { - return ""; - } + String content = Html.fromHtml(divContent.html()).toString(); + char c = 160; + String spaec = "" + c; + content = content.replace(spaec, " "); + content = content.replaceAll("笔趣阁.*最新章节!", ""); + return content; } /** @@ -83,7 +84,7 @@ public class TianLaiReadCrawler implements ReadCrawler { Element dl = divList.getElementsByTag("dl").get(0); String lastTile = null; int i = 0; - for(Element dd : dl.getElementsByTag("dd")){ + for (Element dd : dl.getElementsByTag("dd")) { Elements as = dd.getElementsByTag("a"); if (as.size() > 0) { Element a = as.get(0); @@ -97,7 +98,7 @@ public class TianLaiReadCrawler implements ReadCrawler { String url = a.attr("href"); if (url.contains("files/article/html")) { url = NAME_SPACE + url; - }else { + } else { url = readUrl + url; } chapter.setUrl(url); diff --git a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/WoLongReadCrawler.java b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/WoLongReadCrawler.java index d53bace..f70645d 100644 --- a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/WoLongReadCrawler.java +++ b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/WoLongReadCrawler.java @@ -57,15 +57,11 @@ public class WoLongReadCrawler implements ReadCrawler { public String getContentFormHtml(String html) { Document doc = Jsoup.parse(html); Element divContent = doc.getElementById("contentsource"); - if (divContent != null) { - String content = Html.fromHtml(divContent.html()).toString(); - char c = 160; - String spaec = "" + c; - content = content.replace(spaec, " "); - return content; - } else { - return ""; - } + String content = Html.fromHtml(divContent.html()).toString(); + char c = 160; + String spaec = "" + c; + content = content.replace(spaec, " "); + return content; } /** @@ -95,19 +91,19 @@ public class WoLongReadCrawler implements ReadCrawler { /** * 从搜索html中得到书列表 -
    - -

    大主宰之混子日常

    -

    錯過过错 2019-08-06 19:14

    -
    -
    -

    作者很懒,什么也没有留下。...

    - -
    + *
    + * + *

    大主宰之混子日常

    + *

    錯過过错 2019-08-06 19:14

    + *
    + *
    + *

    作者很懒,什么也没有留下。...

    + * + *
    */ public ConcurrentMultiValueMap getBooksFromSearchHtml(String html) { ConcurrentMultiValueMap books = new ConcurrentMultiValueMap<>(); diff --git a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/XBiQuGeReadCrawler.java b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/XBiQuGeReadCrawler.java new file mode 100644 index 0000000..db18ee2 --- /dev/null +++ b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/XBiQuGeReadCrawler.java @@ -0,0 +1,146 @@ +package xyz.fycz.myreader.webapi.crawler.read; + +import android.text.Html; + +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.nodes.Element; +import org.jsoup.select.Elements; + +import java.util.ArrayList; + +import xyz.fycz.myreader.entity.SearchBookBean; +import xyz.fycz.myreader.enums.BookSource; +import xyz.fycz.myreader.greendao.entity.Book; +import xyz.fycz.myreader.greendao.entity.Chapter; +import xyz.fycz.myreader.model.mulvalmap.ConcurrentMultiValueMap; +import xyz.fycz.myreader.webapi.crawler.base.BookInfoCrawler; +import xyz.fycz.myreader.webapi.crawler.base.ReadCrawler; + + +public class XBiQuGeReadCrawler implements ReadCrawler { + public static final String NAME_SPACE = "https://www.xquge.com"; + public static final String NOVEL_SEARCH = "https://www.xquge.com/search?keyword={key}&sign="; + public static final String CHARSET = "UTF-8"; + public static final String SEARCH_CHARSET = "UTF-8"; + + @Override + public String getSearchLink() { + return NOVEL_SEARCH; + } + + @Override + public String getCharset() { + return CHARSET; + } + + @Override + public String getNameSpace() { + return NAME_SPACE; + } + + @Override + public Boolean isPost() { + return false; + } + + @Override + public String getSearchCharset() { + return SEARCH_CHARSET; + } + + /** + * 从html中获取章节正文 + * + * @param html + * @return + */ + public String getContentFormHtml(String html) { + Document doc = Jsoup.parse(html); + Element divContent = doc.getElementById("content"); + String content = Html.fromHtml(divContent.html()).toString(); + char c = 160; + String spaec = "" + c; + content = content.replace(spaec, " ").replace("applyChapterSetting();", ""); + return content; + } + + /** + * 从html中获取章节列表 + * + * @param html + * @return + */ + public ArrayList getChaptersFromHtml(String html) { + ArrayList chapters = new ArrayList<>(); + Document doc = Jsoup.parse(html); + Element divList = doc.getElementsByClass("catelog_list").last(); + Elements elementsByTag = divList.getElementsByTag("a"); + int i = 0; + for (int j = 0; j < elementsByTag.size(); j++) { + Element a = elementsByTag.get(j); + String title = a.text(); + String url = a.attr("href"); + Chapter chapter = new Chapter(); + chapter.setNumber(i++); + chapter.setTitle(title); + chapter.setUrl(url); + chapters.add(chapter); + } + return chapters; + } + + /** + * 从搜索html中得到书列表 + * + * @param html + * @return
  • + *
    + *
    绝世元尊
    + *
    + * + *
    范范的萧玄幻奇幻连载 + *
    + *
    + * “怎么回事?” 冷尧一脸茫然、这是哪儿、他看着这个陌生的的环境,一时不知所错…… 啊!!! 冷尧看着自己有一双粗大而又充满爆发力的大手,每个细胞都充满爆发力。 这具身体不是自己的,难道我穿越了? …… …… ……
    + *
    + *
    2020-08-28 04:24
    + * + *
    + *
    + * + *
    + *
  • + */ + public ConcurrentMultiValueMap getBooksFromSearchHtml(String html) { + ConcurrentMultiValueMap books = new ConcurrentMultiValueMap<>(); + Document doc = Jsoup.parse(html); + Elements divs = doc.getElementsByClass("rank_ullist"); + Element div = divs.get(0); + Elements elementsByTag = div.getElementsByTag("li"); + for (int i = 0; i < elementsByTag.size(); i++) { + Element element = elementsByTag.get(i); + Book book = new Book(); + Elements as = element.getElementsByTag("a"); + book.setName(as.get(1).text()); + book.setChapterUrl(as.get(1).attr("href")); + book.setNewestChapterTitle(as.get(2).text().replace("更新章节:", "")); + String img = as.first().selectFirst("img").attr("src"); + if (!img.contains("http")) img = "https:" + img; + book.setImgUrl(img); + Elements spans = element.selectFirst(".rank_bkinfo").select("span"); + book.setAuthor(spans.first().text()); + book.setType(spans.get(1).text()); + book.setDesc(element.selectFirst(".rank_bkbrief").text()); + book.setSource(BookSource.xbiquge.toString()); + SearchBookBean sbb = new SearchBookBean(book.getName(), book.getAuthor()); + books.add(sbb, book); + } + return books; + } + +} diff --git a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/XS7ReadCrawler.java b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/XS7ReadCrawler.java index 715c869..16aa4f4 100644 --- a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/XS7ReadCrawler.java +++ b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/XS7ReadCrawler.java @@ -81,15 +81,11 @@ public class XS7ReadCrawler extends FindCrawler implements ReadCrawler { public String getContentFormHtml(String html) { Document doc = Jsoup.parse(html); Element divContent = doc.getElementById("content"); - if (divContent != null) { - String content = Html.fromHtml(divContent.html()).toString(); - char c = 160; - String spaec = "" + c; - content = content.replace(spaec, " ").replaceAll("一秒记住.*免费阅读!", ""); - return content; - } else { - return ""; - } + String content = Html.fromHtml(divContent.html()).toString(); + char c = 160; + String spaec = "" + c; + content = content.replace(spaec, " ").replaceAll("一秒记住.*免费阅读!", ""); + return content; } /** @@ -128,21 +124,21 @@ public class XS7ReadCrawler extends FindCrawler implements ReadCrawler { ConcurrentMultiValueMap books = new ConcurrentMultiValueMap<>(); Document doc = Jsoup.parse(html); // try { - Element alist = doc.getElementById("alist"); - Elements divs = alist.select("#alistbox"); - for (Element div : divs){ - Elements as = div.getElementsByTag("a"); - Book book = new Book(); - book.setName(as.get(1).text()); - book.setAuthor(div.getElementsByTag("span").first().text().replace("作者:", "")); - book.setNewestChapterTitle(as.get(2).text()); - book.setDesc(div.getElementsByClass("intro").first().text()); - book.setImgUrl(div.getElementsByTag("img").attr("src")); - book.setChapterUrl(as.get(1).attr("href")); - book.setSource(BookSource.xs7.toString()); - SearchBookBean sbb = new SearchBookBean(book.getName(), book.getAuthor()); - books.add(sbb, book); - } + Element alist = doc.getElementById("alist"); + Elements divs = alist.select("#alistbox"); + for (Element div : divs) { + Elements as = div.getElementsByTag("a"); + Book book = new Book(); + book.setName(as.get(1).text()); + book.setAuthor(div.getElementsByTag("span").first().text().replace("作者:", "")); + book.setNewestChapterTitle(as.get(2).text()); + book.setDesc(div.getElementsByClass("intro").first().text()); + book.setImgUrl(div.getElementsByTag("img").attr("src")); + book.setChapterUrl(as.get(1).attr("href")); + book.setSource(BookSource.xs7.toString()); + SearchBookBean sbb = new SearchBookBean(book.getName(), book.getAuthor()); + books.add(sbb, book); + } // } catch (Exception e) { // e.printStackTrace(); // } @@ -155,7 +151,7 @@ public class XS7ReadCrawler extends FindCrawler implements ReadCrawler { Document doc = Jsoup.parse(html); Element div = doc.getElementsByClass("subnav-hot").first(); Elements as = div.getElementsByTag("a"); - for (Element a : as){ + for (Element a : as) { BookType bookType = new BookType(); bookType.setUrl(a.attr("href")); bookType.setTypeName(a.text()); @@ -192,7 +188,7 @@ public class XS7ReadCrawler extends FindCrawler implements ReadCrawler { bookType.setPageSize(Integer.parseInt(last.text())); Element div = doc.getElementById("alist"); Elements bDivs = div.select("div[id=alistbox]"); - for (Element bDiv : bDivs){ + for (Element bDiv : bDivs) { Book book = new Book(); Element title = bDiv.getElementsByClass("title").first(); Element sys = bDiv.getElementsByClass("sys").first(); @@ -212,7 +208,7 @@ public class XS7ReadCrawler extends FindCrawler implements ReadCrawler { @Override public boolean getTypePage(BookType curType, int page) { - if (page != 1 && page > curType.getPageSize()){ + if (page != 1 && page > curType.getPageSize()) { return true; } curType.setUrl(curType.getUrl().substring(0, curType.getUrl().lastIndexOf("_") + 1) + page + ".html"); diff --git a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/XS7ReadCrawler2.java b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/XS7ReadCrawler2.java new file mode 100644 index 0000000..a2d0e5f --- /dev/null +++ b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/XS7ReadCrawler2.java @@ -0,0 +1,172 @@ +package xyz.fycz.myreader.webapi.crawler.read; + +import android.text.Html; + +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.nodes.Element; +import org.jsoup.select.Elements; + +import java.util.ArrayList; + +import xyz.fycz.myreader.entity.SearchBookBean; +import xyz.fycz.myreader.enums.BookSource; +import xyz.fycz.myreader.greendao.entity.Book; +import xyz.fycz.myreader.greendao.entity.Chapter; +import xyz.fycz.myreader.model.mulvalmap.ConcurrentMultiValueMap; +import xyz.fycz.myreader.util.StringHelper; +import xyz.fycz.myreader.webapi.crawler.base.BookInfoCrawler; +import xyz.fycz.myreader.webapi.crawler.base.ReadCrawler; + + +public class XS7ReadCrawler2 implements ReadCrawler, BookInfoCrawler { + public static final String NAME_SPACE = "https://www.xs7.co"; + public static final String NOVEL_SEARCH = "https://www.xs7.co/modules/article/search.php?searchkey={key}&submit=%CB%D1%CB%F7"; + public static final String CHARSET = "GBK"; + public static final String SEARCH_CHARSET = "GBK"; + + @Override + public String getSearchLink() { + return NOVEL_SEARCH; + } + + @Override + public String getCharset() { + return CHARSET; + } + + @Override + public String getNameSpace() { + return NAME_SPACE; + } + + @Override + public Boolean isPost() { + return false; + } + + @Override + public String getSearchCharset() { + return SEARCH_CHARSET; + } + + /** + * 从html中获取章节正文 + * + * @param html + * @return + */ + public String getContentFormHtml(String html) { + Document doc = Jsoup.parse(html); + Element divContent = doc.getElementById("content"); + String content = Html.fromHtml(divContent.html()).toString(); + char c = 160; + String spaec = "" + c; + content = content.replace(spaec, " ") + .replaceAll("^.*最新章节!", ""); + return content; + } + + /** + * 从html中获取章节列表 + * + * @param html + * @return + */ + public ArrayList getChaptersFromHtml(String html) { + ArrayList chapters = new ArrayList<>(); + Document doc = Jsoup.parse(html); + String readUrl = doc.select("meta[property=og:novel:read_url]").attr("content"); + Element divList = doc.selectFirst(".zjlist"); + String lastTile = null; + int i = 0; + Elements elementsByTag = divList.getElementsByTag("a"); + for (int j = 0; j < elementsByTag.size(); j++) { + Element a = elementsByTag.get(j); + String title = a.text(); + if (!StringHelper.isEmpty(lastTile) && title.equals(lastTile)) { + continue; + } + Chapter chapter = new Chapter(); + chapter.setNumber(i++); + chapter.setTitle(title); + String url = readUrl + a.attr("href"); + chapter.setUrl(url); + chapters.add(chapter); + lastTile = title; + } + return chapters; + } + + /** + * 从搜索html中得到书列表 + * + * @param html + * @return + * 文娱大主宰 + * 很抱歉,是时候结束了。 + * 羽林都督 + * 480K + * 20-10-02 + * 连载 + * + */ + public ConcurrentMultiValueMap getBooksFromSearchHtml(String html) { + ConcurrentMultiValueMap books = new ConcurrentMultiValueMap<>(); + Document doc = Jsoup.parse(html); + String urlType = doc.select("meta[property=og:type]").attr("content"); + if ("novel".equals(urlType)) { + String readUrl = doc.select("meta[property=og:novel:read_url]").attr("content"); + Book book = new Book(); + book.setChapterUrl(readUrl); + getBookInfo(html, book); + SearchBookBean sbb = new SearchBookBean(book.getName(), book.getAuthor()); + books.add(sbb, book); + } else { + Element div = doc.getElementById("main"); + Elements elements = div.getElementsByTag("tr"); + for (int i = 1; i < elements.size(); i++) { + Element element = elements.get(i); + Book book = new Book(); + Elements info = element.getElementsByTag("td"); + book.setName(info.get(0).text()); + book.setChapterUrl(info.get(0).selectFirst("a").attr("href")); + book.setAuthor(info.get(2).text()); + book.setNewestChapterTitle(info.get(1).text()); + book.setSource(BookSource.xs7.toString()); + SearchBookBean sbb = new SearchBookBean(book.getName(), book.getAuthor()); + books.add(sbb, book); + } + } + return books; + } + + /** + * 获取书籍详细信息 + * + * @param book + */ + public Book getBookInfo(String html, Book book) { + Document doc = Jsoup.parse(html); + book.setSource(BookSource.xs7.toString()); + + String name = doc.select("meta[property=og:title]").attr("content"); + book.setName(name); + String url = doc.select("meta[property=og:novel:read_url]").attr("content"); + book.setChapterUrl(url); + String author = doc.select("meta[property=og:novel:author]").attr("content"); + book.setAuthor(author); + String newestChapter = doc.select("meta[property=og:novel:latest_chapter_name]").attr("content"); + book.setNewestChapterTitle(newestChapter); + + Element img = doc.getElementById("picbox"); + book.setImgUrl(img.getElementsByTag("img").get(0).attr("src")); + Element desc = doc.getElementById("intro"); + book.setDesc(Html.fromHtml(desc.html()).toString()); + //类型 + String type = doc.select("meta[property=og:novel:category]").attr("content"); + book.setType(type); + return book; + } + +} diff --git a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/XiaGuReadCrawler.java b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/XiaGuReadCrawler.java index 030115c..816768b 100644 --- a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/XiaGuReadCrawler.java +++ b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/XiaGuReadCrawler.java @@ -58,25 +58,21 @@ public class XiaGuReadCrawler implements ReadCrawler { public String getContentFormHtml(String html) { Document doc = Jsoup.parse(html); Element divContent = doc.getElementById("txt"); - if (divContent != null) { - Elements aDiv = divContent.getElementsByTag("dd"); - StringBuilder sb = new StringBuilder(); - Collections.sort(aDiv, (o1, o2) -> Integer.parseInt(o1.attr("data-id")) - - Integer.parseInt(o2.attr("data-id"))); - for (int i = 0; i < aDiv.size(); i++) { - Element dd = aDiv.get(i); - if (i == aDiv.size() - 1) break; - sb.append(Html.fromHtml(dd.html()).toString()); - sb.append("\n"); - } - String content = sb.toString(); - char c = 160; - String spaec = "" + c; - content = content.replace(spaec, " "); - return content; - } else { - return ""; + Elements aDiv = divContent.getElementsByTag("dd"); + StringBuilder sb = new StringBuilder(); + Collections.sort(aDiv, (o1, o2) -> Integer.parseInt(o1.attr("data-id")) - + Integer.parseInt(o2.attr("data-id"))); + for (int i = 0; i < aDiv.size(); i++) { + Element dd = aDiv.get(i); + if (i == aDiv.size() - 1) break; + sb.append(Html.fromHtml(dd.html()).toString()); + sb.append("\n"); } + String content = sb.toString(); + char c = 160; + String spaec = "" + c; + content = content.replace(spaec, " "); + return content; } /** @@ -138,24 +134,24 @@ public class XiaGuReadCrawler implements ReadCrawler { ConcurrentMultiValueMap books = new ConcurrentMultiValueMap<>(); Document doc = Jsoup.parse(html); // try { - Element div = doc.getElementsByClass("subject-list").first(); - Elements lis = div.getElementsByTag("li"); - for (Element li : lis){ - Elements as = li.getElementsByTag("a"); - Book book = new Book(); - book.setName(as.get(1).text()); - book.setAuthor(as.get(2).text()); - book.setType(as.get(3).text()); - book.setNewestChapterTitle(as.get(4).text().replace("【最新章节】", "")); - book.setDesc(li.getElementsByTag("p").first().text()); - String imgUrl = li.getElementsByTag("img").attr("data-original"); - book.setImgUrl(!imgUrl.contains("http") ? "https:" + imgUrl : imgUrl); - //https://www.xiagu.org/xs/5584.html -> https://www.xiagu.org/read/5/5584/ - book.setChapterUrl(NAME_SPACE + as.get(1).attr("href").replace("xs", "read/1").replace(".html", "/")); - book.setSource(BookSource.xiagu.toString()); - SearchBookBean sbb = new SearchBookBean(book.getName(), book.getAuthor()); - books.add(sbb, book); - } + Element div = doc.getElementsByClass("subject-list").first(); + Elements lis = div.getElementsByTag("li"); + for (Element li : lis) { + Elements as = li.getElementsByTag("a"); + Book book = new Book(); + book.setName(as.get(1).text()); + book.setAuthor(as.get(2).text()); + book.setType(as.get(3).text()); + book.setNewestChapterTitle(as.get(4).text().replace("【最新章节】", "")); + book.setDesc(li.getElementsByTag("p").first().text()); + String imgUrl = li.getElementsByTag("img").attr("data-original"); + book.setImgUrl(!imgUrl.contains("http") ? "https:" + imgUrl : imgUrl); + //https://www.xiagu.org/xs/5584.html -> https://www.xiagu.org/read/5/5584/ + book.setChapterUrl(NAME_SPACE + as.get(1).attr("href").replace("xs", "read/1").replace(".html", "/")); + book.setSource(BookSource.xiagu.toString()); + SearchBookBean sbb = new SearchBookBean(book.getName(), book.getAuthor()); + books.add(sbb, book); + } // } catch (Exception e) { // e.printStackTrace(); // } diff --git a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/XingXingReadCrawler.java b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/XingXingReadCrawler.java index 1226d51..716dbc5 100644 --- a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/XingXingReadCrawler.java +++ b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/XingXingReadCrawler.java @@ -58,15 +58,11 @@ public class XingXingReadCrawler implements ReadCrawler { public String getContentFormHtml(String html) { Document doc = Jsoup.parse(html); Element divContent = doc.getElementById("txt"); - if (divContent != null) { - String content = Html.fromHtml(divContent.html()).toString(); - char c = 160; - String spaec = "" + c; - content = content.replace(spaec, " "); - return content; - } else { - return ""; - } + String content = Html.fromHtml(divContent.html()).toString(); + char c = 160; + String spaec = "" + c; + content = content.replace(spaec, " "); + return content; } /** @@ -131,23 +127,23 @@ public class XingXingReadCrawler implements ReadCrawler { ConcurrentMultiValueMap books = new ConcurrentMultiValueMap<>(); Document doc = Jsoup.parse(html); // try { - Element div = doc.getElementsByClass("leftBox").first(); - Elements lis = div.getElementsByTag("li"); - for (Element li : lis){ - Elements as = li.getElementsByTag("a"); - Book book = new Book(); - book.setName(as.get(1).text()); - book.setAuthor(li.getElementsByTag("span").first().text()); - book.setType(as.get(2).text()); - book.setNewestChapterTitle(as.get(3).text()); - book.setDesc(li.getElementsByClass("c").first().text().replace("内容介绍:", "")); - book.setUpdateDate(li.getElementsByClass("time2").first().text().replace("更新时间:", "")); - book.setImgUrl(li.getElementsByTag("img").attr("data-original")); - book.setChapterUrl(NAME_SPACE + as.get(1).attr("href").replace(".html", "/")); - book.setSource(BookSource.xingxing.toString()); - SearchBookBean sbb = new SearchBookBean(book.getName(), book.getAuthor()); - books.add(sbb, book); - } + Element div = doc.getElementsByClass("leftBox").first(); + Elements lis = div.getElementsByTag("li"); + for (Element li : lis) { + Elements as = li.getElementsByTag("a"); + Book book = new Book(); + book.setName(as.get(1).text()); + book.setAuthor(li.getElementsByTag("span").first().text()); + book.setType(as.get(2).text()); + book.setNewestChapterTitle(as.get(3).text()); + book.setDesc(li.getElementsByClass("c").first().text().replace("内容介绍:", "")); + book.setUpdateDate(li.getElementsByClass("time2").first().text().replace("更新时间:", "")); + book.setImgUrl(li.getElementsByTag("img").attr("data-original")); + book.setChapterUrl(NAME_SPACE + as.get(1).attr("href").replace(".html", "/")); + book.setSource(BookSource.xingxing.toString()); + SearchBookBean sbb = new SearchBookBean(book.getName(), book.getAuthor()); + books.add(sbb, book); + } // } catch (Exception e) { // e.printStackTrace(); // } diff --git a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/YanQingLouReadCrawler.java b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/YanQingLouReadCrawler.java index edb2dac..7e829f1 100644 --- a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/YanQingLouReadCrawler.java +++ b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/YanQingLouReadCrawler.java @@ -58,68 +58,65 @@ public class YanQingLouReadCrawler implements ReadCrawler { } /* - var preview_page = "/lishi/220987/60.html"; - var next_page = "/lishi/220987/62.html"; - var index_page = "/lishi/220987/"; - var article_id = "220987"; - var chapter_id = "61"; - var nextcid = "62"; - var prevcid = "60"; - var articlename = "临高启明"; - var chaptername = "第十五节 遇伏"; - var hash = "38e338d183600e17"; - var localpre = "www.yanqinglou.com"; - */ - /** - * 从html中获取章节正文 - * - * @param html - * @return + var preview_page = "/lishi/220987/60.html"; + var next_page = "/lishi/220987/62.html"; + var index_page = "/lishi/220987/"; + var article_id = "220987"; + var chapter_id = "61"; + var nextcid = "62"; + var prevcid = "60"; + var articlename = "临高启明"; + var chaptername = "第十五节 遇伏"; + var hash = "38e338d183600e17"; + var localpre = "www.yanqinglou.com"; */ public String getContentFormHtml(String html) { Document doc = Jsoup.parse(html); Element divContent = doc.getElementById("content"); - if (divContent != null) { - String content = Html.fromHtml(divContent.html()).toString(); - char c = 160; - String spaec = "" + c; - content = content.replace(spaec, " ") - .replaceAll("您可以.*最新章节!", "") - .replaceAll("转码页面.*com/", ""); - return content; - } else { - return ""; + String content = ""; + content = Html.fromHtml(divContent.html()).toString(); + try { + if (content.contains("正在加载") || content.contains("本章未完,点击下一页继续阅读")) { + content = getAjaxContent(html); + } + /*if (content.contains("本章未完,点击下一页继续阅读")){ + String nextUrl = doc.select(".to_nextpage") + .first().select("a").first() + .attr("href"); + content = content.replace("本章未完,点击下一页继续阅读", "") + .replace("-->>", ""); + content += getContentFormHtml(OkHttpUtils.getHtml(NAME_SPACE + nextUrl, CHARSET)); + }*/ + } catch (IOException | JSONException e) { + e.printStackTrace(); } + char c = 160; + String spaec = "" + c; + content = content.replace(spaec, " ") + .replaceAll("您可以.*最新章节!", "") + .replaceAll("转码页.*com/", ""); + return content; } + /* id: 220987 eKey: fe9535a08b53e929 cid: 62 basecid: 62 */ - public void getAjaxContent(String html, ResultCallback callback){ + public String getAjaxContent(String html) throws IOException, JSONException { String id = StringUtils.getSubString(html, "var article_id = \"", "\";"); String eKey = StringUtils.getSubString(html, "var hash = \"", "\";"); String cid = StringUtils.getSubString(html, "var chapter_id = \"", "\";"); String body = "id=" + id + "&eKey=" + eKey + "&cid=" + cid + "&basecid=" + cid; MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded"); RequestBody requestBody = RequestBody.create(mediaType, body); - try { - String jsonStr = OkHttpUtils.getHtml(AJAX_CONTENT, requestBody, CHARSET); - JSONObject json = new JSONObject(jsonStr); - String content = json.getJSONObject("info").getString("content"); - content = Html.fromHtml(content).toString(); - char c = 160; - String spaec = "" + c; - content = content.replace(spaec, " ") - .replaceAll("您可以.*最新章节!", "") - .replaceAll("转码页面.*com/", ""); - callback.onFinish(content, 0); - } catch (IOException | JSONException e) { - e.printStackTrace(); - callback.onError(e); - } + String jsonStr = OkHttpUtils.getHtml(AJAX_CONTENT, requestBody, CHARSET); + JSONObject json = new JSONObject(jsonStr); + String content = json.getJSONObject("info").getString("content"); + content = Html.fromHtml(content).toString(); + return content; } /** @@ -148,18 +145,18 @@ public class YanQingLouReadCrawler implements ReadCrawler { /** * 从搜索html中得到书列表 -
    -
    斗罗之大主宰 -
    -

    斗罗之大主宰

    -
    作者:上弦666
    -
    分类:婚恋
    -
    更新到:最近更新>>
    -
    简介:叶辰,武魂,昊天锤的变异,大须弥锤!昊天锤本就是大陆第一器武魂,而武魂是大须弥锤的叶辰,会有多强?当
    -
    - -
    -
    + *
    + *
    斗罗之大主宰 + *
    + *

    斗罗之大主宰

    + *
    作者:上弦666
    + *
    分类:婚恋
    + *
    更新到:最近更新>>
    + *
    简介:叶辰,武魂,昊天锤的变异,大须弥锤!昊天锤本就是大陆第一器武魂,而武魂是大须弥锤的叶辰,会有多强?当
    + *
    + * + *
    + *
    */ public ConcurrentMultiValueMap getBooksFromSearchHtml(String html) { ConcurrentMultiValueMap books = new ConcurrentMultiValueMap<>(); @@ -182,7 +179,7 @@ public class YanQingLouReadCrawler implements ReadCrawler { SearchBookBean sbb = new SearchBookBean(book.getName(), book.getAuthor()); books.add(sbb, book); } - }else { + } else { Book book = new Book(); getBookInfo(doc, book); SearchBookBean sbb = new SearchBookBean(book.getName(), book.getAuthor()); diff --git a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/YunZhongReadCrawler.java b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/YunZhongReadCrawler.java index a25af51..e9d166f 100644 --- a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/YunZhongReadCrawler.java +++ b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/YunZhongReadCrawler.java @@ -5,6 +5,7 @@ import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.nodes.TextNode; import org.jsoup.select.Elements; + import xyz.fycz.myreader.entity.SearchBookBean; import xyz.fycz.myreader.enums.BookSource; import xyz.fycz.myreader.greendao.entity.Book; @@ -56,20 +57,16 @@ public class YunZhongReadCrawler implements ReadCrawler, BookInfoCrawler { public String getContentFormHtml(String html) { Document doc = Jsoup.parse(html); Element divContent = doc.getElementsByClass("box_box").first(); - if (divContent != null) { - StringBuilder sb = new StringBuilder(); - for (TextNode textNode : divContent.textNodes()){ - sb.append(textNode.text()); - sb.append("\n"); - } - String content = sb.toString(); - char c = 160; - String spaec = "" + c; - content = content.replace(spaec, " "); - return content; - } else { - return ""; + StringBuilder sb = new StringBuilder(); + for (TextNode textNode : divContent.textNodes()) { + sb.append(textNode.text()); + sb.append("\n"); } + String content = sb.toString(); + char c = 160; + String spaec = "" + c; + content = content.replace(spaec, " "); + return content; } /** @@ -110,23 +107,23 @@ public class YunZhongReadCrawler implements ReadCrawler, BookInfoCrawler { public ConcurrentMultiValueMap getBooksFromSearchHtml(String html) { ConcurrentMultiValueMap books = new ConcurrentMultiValueMap<>(); // try { - Document doc = Jsoup.parse(html); - Elements divs = doc.getElementsByClass("ul_b_list"); - Element div = divs.get(0); - Elements elementsByTag = div.getElementsByTag("li"); - for (Element element : elementsByTag) { - Book book = new Book(); - Element info = element.getElementsByTag("h2").first(); - book.setName(info.getElementsByTag("a").first().text()); - book.setType(info.getElementsByTag("span").first().text()); - book.setAuthor(element.getElementsByClass("state").first().text().replaceAll("作者.|类型.*", "")); - book.setImgUrl(NAME_SPACE + element.getElementsByClass("pic").first().getElementsByTag("img").first().attr("src")); - book.setChapterUrl(NAME_SPACE + element.getElementsByTag("a").first().attr("href")); - book.setNewestChapterTitle(""); - book.setSource(BookSource.yunzhong.toString()); - SearchBookBean sbb = new SearchBookBean(book.getName(), book.getAuthor()); - books.add(sbb, book); - } + Document doc = Jsoup.parse(html); + Elements divs = doc.getElementsByClass("ul_b_list"); + Element div = divs.get(0); + Elements elementsByTag = div.getElementsByTag("li"); + for (Element element : elementsByTag) { + Book book = new Book(); + Element info = element.getElementsByTag("h2").first(); + book.setName(info.getElementsByTag("a").first().text()); + book.setType(info.getElementsByTag("span").first().text()); + book.setAuthor(element.getElementsByClass("state").first().text().replaceAll("作者.|类型.*", "")); + book.setImgUrl(NAME_SPACE + element.getElementsByClass("pic").first().getElementsByTag("img").first().attr("src")); + book.setChapterUrl(NAME_SPACE + element.getElementsByTag("a").first().attr("href")); + book.setNewestChapterTitle(""); + book.setSource(BookSource.yunzhong.toString()); + SearchBookBean sbb = new SearchBookBean(book.getName(), book.getAuthor()); + books.add(sbb, book); + } // } catch (Exception e) { // e.printStackTrace(); // } diff --git a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/ZW37ReadCrawler.java b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/ZW37ReadCrawler.java new file mode 100644 index 0000000..e09495f --- /dev/null +++ b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/ZW37ReadCrawler.java @@ -0,0 +1,170 @@ +package xyz.fycz.myreader.webapi.crawler.read; + +import android.text.Html; + +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.nodes.Element; +import org.jsoup.select.Elements; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import xyz.fycz.myreader.entity.SearchBookBean; +import xyz.fycz.myreader.entity.bookstore.BookType; +import xyz.fycz.myreader.enums.BookSource; +import xyz.fycz.myreader.greendao.entity.Book; +import xyz.fycz.myreader.greendao.entity.Chapter; +import xyz.fycz.myreader.model.mulvalmap.ConcurrentMultiValueMap; +import xyz.fycz.myreader.util.StringHelper; +import xyz.fycz.myreader.webapi.crawler.base.BookInfoCrawler; +import xyz.fycz.myreader.webapi.crawler.base.ReadCrawler; + + +public class ZW37ReadCrawler implements ReadCrawler, BookInfoCrawler { + private static final String NAME_SPACE = "https://www.37zww.net"; + private static final String NOVEL_SEARCH = "https://www.37zww.net/modules/article/search.php?searchtype=articlename&searchkey={key}"; + private static final String CHARSET = "GBK"; + public static final String SEARCH_CHARSET = "GBK"; + + @Override + public String getSearchLink() { + return NOVEL_SEARCH; + } + + @Override + public String getNameSpace() { + return NAME_SPACE; + } + + @Override + public Boolean isPost() { + return false; + } + + @Override + public String getCharset() { + return CHARSET; + } + + @Override + public String getSearchCharset() { + return SEARCH_CHARSET; + } + + + @Override + public String getContentFormHtml(String html) { + Document doc = Jsoup.parse(html); + Element divContent = doc.getElementById("content"); + String content = Html.fromHtml(divContent.html()).toString(); + char c = 160; + String spaec = "" + c; + content = content.replace(spaec, " "); + return content; + } + + @Override + public ArrayList getChaptersFromHtml(String html) { + ArrayList chapters = new ArrayList<>(); + Document doc = Jsoup.parse(html); + String readUrl = doc.select("meta[property=og:novel:read_url]").attr("content"); + Element divList = doc.getElementById("list"); + String lastTile = null; + int i = 0; + Elements elementsByTag = divList.getElementsByTag("a"); + for (int j = 0; j < elementsByTag.size(); j++) { + Element a = elementsByTag.get(j); + String title = a.text(); + if (!StringHelper.isEmpty(lastTile) && title.equals(lastTile)) { + continue; + } + Chapter chapter = new Chapter(); + chapter.setNumber(i++); + chapter.setTitle(title); + String url = readUrl + a.attr("href"); + chapter.setUrl(url); + chapters.add(chapter); + lastTile = title; + } + return chapters; + } + + /** + * 从搜索html中得到书列表 + * + * @param html + * @return + * 斗罗大陆IV终极斗罗 + * 第一千五百八十一章 突破,真神级! + * 唐家三少 + * 8427K + * 21-02-06 + * 连载 + * + */ + public ConcurrentMultiValueMap getBooksFromSearchHtml(String html) { + final ConcurrentMultiValueMap books = new ConcurrentMultiValueMap<>(); + Document doc = Jsoup.parse(html); + String urlType = doc.select("meta[property=og:type]").attr("content"); + if ("novel".equals(urlType)) { + String readUrl = doc.select("meta[property=og:novel:read_url]").attr("content"); + Book book = new Book(); + book.setChapterUrl(readUrl); + getBookInfo(html, book); + SearchBookBean sbb = new SearchBookBean(book.getName(), book.getAuthor()); + books.add(sbb, book); + } else { + Element div = doc.getElementById("main"); + Elements elements = div.getElementsByTag("tr"); + for (int i = 1; i < elements.size(); i++) { + Element element = elements.get(i); + Book book = new Book(); + Elements info = element.getElementsByTag("td"); + book.setName(info.get(0).text()); + book.setChapterUrl(info.get(0).selectFirst("a").attr("href")); + book.setAuthor(info.get(2).text()); + book.setNewestChapterTitle(info.get(1).text()); + book.setSource(BookSource.zw37.toString()); + SearchBookBean sbb = new SearchBookBean(book.getName(), book.getAuthor()); + books.add(sbb, book); + } + } + return books; + } + + /** + * 获取小说详细信息 + * + * @param html + * @return + */ + public Book getBookInfo(String html, Book book) { + Document doc = Jsoup.parse(html); + book.setSource(BookSource.zw37.toString()); + + String name = doc.select("meta[property=og:title]").attr("content"); + book.setName(name); + String url = doc.select("meta[property=og:novel:read_url]").attr("content"); + book.setChapterUrl(url); + String author = doc.select("meta[property=og:novel:author]").attr("content"); + book.setAuthor(author); + String newestChapter = doc.select("meta[property=og:novel:latest_chapter_name]").attr("content"); + book.setNewestChapterTitle(newestChapter); + + String img = doc.select("meta[property=og:image]").attr("content"); + book.setImgUrl(img); + + String desc = doc.select("meta[property=og:description]").attr("content"); + book.setDesc(desc); + //类型 + String type = doc.select("meta[property=og:novel:category]").attr("content"); + book.setType(type); + return book; + + } + + +} diff --git a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/ZaiShuYuanReadCrawler.java b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/ZaiShuYuanReadCrawler.java new file mode 100644 index 0000000..aa51042 --- /dev/null +++ b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/ZaiShuYuanReadCrawler.java @@ -0,0 +1,161 @@ +package xyz.fycz.myreader.webapi.crawler.read; + +import android.text.Html; + +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.nodes.Element; +import org.jsoup.select.Elements; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; + +import xyz.fycz.myreader.entity.SearchBookBean; +import xyz.fycz.myreader.entity.bookstore.BookType; +import xyz.fycz.myreader.enums.BookSource; +import xyz.fycz.myreader.greendao.entity.Book; +import xyz.fycz.myreader.greendao.entity.Chapter; +import xyz.fycz.myreader.model.mulvalmap.ConcurrentMultiValueMap; +import xyz.fycz.myreader.webapi.crawler.base.FindCrawler; +import xyz.fycz.myreader.webapi.crawler.base.ReadCrawler; + + +public class ZaiShuYuanReadCrawler implements ReadCrawler { + public static final String NAME_SPACE = "https://www.zhaishuyuan.com"; + public static final String NOVEL_SEARCH = "https://www.zhaishuyuan.com/search/,key={key}"; + public static final String CHARSET = "gbk"; + public static final String SEARCH_CHARSET = "gbk"; + + @Override + public String getSearchLink() { + return NOVEL_SEARCH; + } + + @Override + public String getCharset() { + return CHARSET; + } + + @Override + public String getNameSpace() { + return NAME_SPACE; + } + + @Override + public Boolean isPost() { + return true; + } + + @Override + public String getSearchCharset() { + return SEARCH_CHARSET; + } + + /** + * 从html中获取章节正文 + * + * @param html + * @return + */ + public String getContentFormHtml(String html) { + Document doc = Jsoup.parse(html); + Element divContent = doc.getElementById("content"); + String content = Html.fromHtml(divContent.html()).toString(); + char c = 160; + String spaec = "" + c; + content = content.replace(spaec, " ").replaceAll("您可以在.*最新章节!|\\\\", ""); + return content; + } + + /** + * 从html中获取章节列表 + * + * @param html + * @return + */ + public ArrayList getChaptersFromHtml(String html) { + ArrayList chapters = new ArrayList<>(); + Document doc = Jsoup.parse(html); + Element divList = doc.getElementById("readerlist"); + Elements elementsByTag = divList.getElementsByTag("a"); + int i = 0; + for (int j = 0; j < elementsByTag.size(); j++) { + Element a = elementsByTag.get(j); + String title = a.text(); + String url = a.attr("href"); + Chapter chapter = new Chapter(); + chapter.setNumber(i++); + chapter.setTitle(title); + chapter.setUrl(NAME_SPACE + url); + chapters.add(chapter); + } + return chapters; + } + + /** + * 从搜索html中得到书列表 + * + * @param html + * @return
    + *
    <font color=#F30>大主宰</font>
    + *

    大主宰别名:大主宰

    + *
    作者:天蚕土豆状态:已完结小类:异世大陆字数:4944063标签:热血 爽文
    + *
    大千世界,位面交汇,万族林立,群雄荟萃,一位位来自下位面的天之至尊,在这无尽世界,演绎着令人向往的传奇,追求着那主宰之路。无尽火域,炎帝执掌,万火焚苍穹。武境之内,武祖之威,震慑乾坤。西天之殿,百战之皇,战威无可敌。北荒之丘,万墓之地,不死…
    + *
    最新章节:第一千五百五十一章 邪神陨落(大结局) 更新时间:2020-2-26 13:26:49
    + *
    + */ + public ConcurrentMultiValueMap getBooksFromSearchHtml(String html) { + ConcurrentMultiValueMap books = new ConcurrentMultiValueMap<>(); + Document doc = Jsoup.parse(html); + String urlType = doc.select("meta[property=og:type]").attr("content"); + if ("novel".equals(urlType)) { + String readUrl = doc.select("meta[property=og:novel:read_url]").attr("content"); + Book book = new Book(); + book.setChapterUrl(readUrl); + getBookInfo(doc, book); + SearchBookBean sbb = new SearchBookBean(book.getName(), book.getAuthor()); + books.add(sbb, book); + } else { + Element div = doc.getElementById("sitembox"); + Elements dls = div.getElementsByTag("dl"); + for (Element dl : dls) { + Elements as = dl.getElementsByTag("a"); + Book book = new Book(); + book.setName(as.get(1).text()); + book.setImgUrl(as.first().getElementsByTag("img").attr("_src")); + book.setNewestChapterTitle(as.last().text()); + Elements spans = dl.selectFirst(".book_other").select("span"); + book.setAuthor(spans.get(0).text()); + book.setType(spans.get(2).text()); + book.setDesc(dl.getElementsByClass("book_des").first().text()); + book.setChapterUrl(NAME_SPACE + as.get(1).attr("href").replace("novel", "read").replace(".html", "/")); + book.setSource(BookSource.zaishuyuan.toString()); + SearchBookBean sbb = new SearchBookBean(book.getName(), book.getAuthor()); + books.add(sbb, book); + } + } + return books; + } + + private void getBookInfo(Document doc, Book book) { + book.setSource(BookSource.zaishuyuan.toString()); + + String name = doc.select("meta[property=og:title]").attr("content"); + book.setName(name); + String url = doc.select("meta[property=og:novel:read_url]").attr("content"); + book.setChapterUrl(url); + String author = doc.select("meta[property=og:novel:author]").attr("content"); + book.setAuthor(author); + String newestChapter = doc.select("meta[property=og:novel:latest_chapter_name]").attr("content"); + book.setNewestChapterTitle(newestChapter); + + String img = doc.select("meta[property=og:image]").attr("content"); + book.setImgUrl(img); + Element desc = doc.getElementById("bookintro"); + book.setDesc(Html.fromHtml(desc.html()).toString()); + //类型 + String type = doc.select("meta[property=og:novel:category]").attr("content"); + book.setType(type); + } +} diff --git a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/ZuoPinReadCrawler.java b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/ZuoPinReadCrawler.java index 6ea7b19..ee38b58 100644 --- a/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/ZuoPinReadCrawler.java +++ b/app/src/main/java/xyz/fycz/myreader/webapi/crawler/read/ZuoPinReadCrawler.java @@ -1,10 +1,12 @@ package xyz.fycz.myreader.webapi.crawler.read; import android.text.Html; + import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; + import xyz.fycz.myreader.entity.SearchBookBean; import xyz.fycz.myreader.enums.BookSource; import xyz.fycz.myreader.greendao.entity.Book; @@ -56,15 +58,11 @@ public class ZuoPinReadCrawler implements ReadCrawler, BookInfoCrawler { public String getContentFormHtml(String html) { Document doc = Jsoup.parse(html); Element divContent = doc.getElementById("htmlContent"); - if (divContent != null) { - String content = Html.fromHtml(divContent.html()).toString(); - char c = 160; - String spaec = "" + c; - content = content.replace(spaec, " "); - return content; - } else { - return ""; - } + String content = Html.fromHtml(divContent.html()).toString(); + char c = 160; + String spaec = "" + c; + content = content.replace(spaec, " "); + return content; } /** diff --git a/app/src/main/java/xyz/fycz/myreader/widget/page/LocalPageLoader.java b/app/src/main/java/xyz/fycz/myreader/widget/page/LocalPageLoader.java index a601c19..3743d34 100644 --- a/app/src/main/java/xyz/fycz/myreader/widget/page/LocalPageLoader.java +++ b/app/src/main/java/xyz/fycz/myreader/widget/page/LocalPageLoader.java @@ -282,7 +282,7 @@ public class LocalPageLoader extends PageLoader { @Override public void onError(Throwable e) { resultCallback.onError((Exception) e); - chapterError(); + chapterError(e.getLocalizedMessage()); Log.d(TAG, "file load error:" + e.toString()); } }); diff --git a/app/src/main/java/xyz/fycz/myreader/widget/page/NetPageLoader.java b/app/src/main/java/xyz/fycz/myreader/widget/page/NetPageLoader.java index b5a73b8..7a69fed 100644 --- a/app/src/main/java/xyz/fycz/myreader/widget/page/NetPageLoader.java +++ b/app/src/main/java/xyz/fycz/myreader/widget/page/NetPageLoader.java @@ -1,29 +1,30 @@ package xyz.fycz.myreader.widget.page; -import android.util.Log; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; import xyz.fycz.myreader.application.MyApplication; -import xyz.fycz.myreader.util.StringHelper; -import xyz.fycz.myreader.util.ToastUtils; -import xyz.fycz.myreader.webapi.callback.ResultCallback; import xyz.fycz.myreader.common.APPCONST; import xyz.fycz.myreader.entity.Setting; import xyz.fycz.myreader.greendao.entity.Book; import xyz.fycz.myreader.greendao.entity.Chapter; import xyz.fycz.myreader.greendao.service.ChapterService; -import xyz.fycz.myreader.webapi.crawler.base.ReadCrawler; import xyz.fycz.myreader.util.utils.FileUtils; import xyz.fycz.myreader.webapi.CommonApi; - -import java.io.*; -import java.util.ArrayList; -import java.util.List; +import xyz.fycz.myreader.webapi.callback.ResultCallback; +import xyz.fycz.myreader.webapi.crawler.base.ReadCrawler; public class NetPageLoader extends PageLoader { private static final String TAG = "PageFactory"; private ChapterService mChapterService; private ReadCrawler mReadCrawler; + private List loadingChapters = new CopyOnWriteArrayList<>(); public NetPageLoader(PageView pageView, Book collBook, ChapterService mChapterService, ReadCrawler mReadCrawler, Setting setting) { @@ -98,7 +99,10 @@ public class NetPageLoader extends PageLoader { boolean parseCurChapter() { boolean isRight = super.parseCurChapter(); - if (mStatus == STATUS_LOADING) { + if (mStatus == STATUS_FINISH) { + loadPrevChapter(); + loadNextChapter(); + } else if (mStatus == STATUS_LOADING) { loadCurrentChapter(); } return isRight; @@ -195,15 +199,16 @@ public class NetPageLoader extends PageLoader { List chapters = new ArrayList<>(); - // 过滤,哪些数据已经加载了 + // 过滤,哪些数据已经加载了/正在加载 for (int i = start; i <= end; ++i) { Chapter txtChapter = mChapterList.get(i); - if (!hasChapterData(txtChapter)) { + if (!hasChapterData(txtChapter) && !loadingChapters.contains(txtChapter)) { chapters.add(txtChapter); } } if (!chapters.isEmpty()) { + loadingChapters.addAll(chapters); for (Chapter chapter : chapters) { getChapterContent(chapter); } @@ -219,8 +224,10 @@ public class NetPageLoader extends PageLoader { CommonApi.getChapterContent(chapter.getUrl(), mReadCrawler, new ResultCallback() { @Override public void onFinish(final Object o, int code) { + loadingChapters.remove(chapter); mChapterService.saveOrUpdateChapter(chapter, (String) o); - if (getPageStatus() == PageLoader.STATUS_LOADING) { + if (isClose()) return; + if (getPageStatus() == PageLoader.STATUS_LOADING && mCurChapterPos == chapter.getNumber()) { MyApplication.runOnUiThread(() -> { if (isPrev) { openChapterInLastPage(); @@ -233,8 +240,10 @@ public class NetPageLoader extends PageLoader { @Override public void onError(Exception e) { + loadingChapters.remove(chapter); + if (isClose()) return; if (mCurChapterPos == chapter.getNumber()) - chapterError(); + chapterError("请尝试重新加载或换源\n" + e.getLocalizedMessage()); e.printStackTrace(); } }); diff --git a/app/src/main/java/xyz/fycz/myreader/widget/page/PageLoader.java b/app/src/main/java/xyz/fycz/myreader/widget/page/PageLoader.java index 65a5827..47b2202 100644 --- a/app/src/main/java/xyz/fycz/myreader/widget/page/PageLoader.java +++ b/app/src/main/java/xyz/fycz/myreader/widget/page/PageLoader.java @@ -17,6 +17,7 @@ import com.gyf.immersionbar.ImmersionBar; import io.reactivex.Single; import io.reactivex.SingleObserver; import io.reactivex.SingleOnSubscribe; +import io.reactivex.disposables.CompositeDisposable; import io.reactivex.disposables.Disposable; import xyz.fycz.myreader.R; import xyz.fycz.myreader.application.MyApplication; @@ -62,6 +63,8 @@ public abstract class PageLoader { public static final int STATUS_PARING = 6; // 正在解析 (装载本地数据) public static final int STATUS_PARSE_ERROR = 7; // 本地文件解析错误(暂未被使用) public static final int STATUS_CATEGORY_EMPTY = 8; // 获取到的目录为空 + + private String errorMsg = ""; // 默认的显示参数配置 public static final int DEFAULT_MARGIN_HEIGHT = 28; public static final int DEFAULT_MARGIN_WIDTH = 15; @@ -106,7 +109,9 @@ public abstract class PageLoader { // private BookRecordBean mBookRecord; //缩进 String indent; - private Disposable mPreLoadDisp; + private Disposable mPreLoadNextDisp; + private Disposable mPreLoadPrevDisp; + private CompositeDisposable compositeDisposable; /*****************params**************************/ // 当前的状态 @@ -175,6 +180,7 @@ public abstract class PageLoader { mContext = pageView.getContext(); mCollBook = collBook; mChapterList = new ArrayList<>(1); + compositeDisposable = new CompositeDisposable(); // 获取配置管理器 mSettingManager = setting; // 初始化数据 @@ -367,8 +373,11 @@ public abstract class PageLoader { // 将上一章的缓存设置为null mPreChapter = null; // 如果当前下一章缓存正在执行,则取消 - if (mPreLoadDisp != null) { - mPreLoadDisp.dispose(); + if (mPreLoadNextDisp != null) { + mPreLoadNextDisp.dispose(); + } + if (mPreLoadPrevDisp != null) { + mPreLoadPrevDisp.dispose(); } // 将下一章缓存设置为null mNextChapter = null; @@ -769,9 +778,10 @@ public abstract class PageLoader { mPageView.drawCurPage(false); } - public void chapterError() { + public void chapterError(String msg) { //加载错误 mStatus = STATUS_ERROR; + errorMsg = msg; mPageView.drawCurPage(false); } @@ -782,8 +792,11 @@ public abstract class PageLoader { isChapterListPrepare = false; isClose = true; - if (mPreLoadDisp != null) { - mPreLoadDisp.dispose(); + if (mPreLoadNextDisp != null) { + mPreLoadNextDisp.dispose(); + } + if (mPreLoadPrevDisp != null) { + mPreLoadPrevDisp.dispose(); } clearList(mChapterList); @@ -1014,7 +1027,7 @@ public abstract class PageLoader { tip = "正在加载目录列表..."; break; case STATUS_ERROR: - tip = "章节内容加载失败"; + tip = "章节内容加载失败\n" + errorMsg; break; case STATUS_EMPTY: tip = "章节内容为空"; @@ -1029,14 +1042,17 @@ public abstract class PageLoader { tip = "目录列表为空"; break; } - - //将提示语句放到正中间 - Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics(); - float textHeight = fontMetrics.top - fontMetrics.bottom; - float textWidth = mTextPaint.measureText(tip); - float pivotX = (mDisplayWidth - textWidth) / 2; - float pivotY = (mDisplayHeight - textHeight) / 2; - canvas.drawText(tip, pivotX, pivotY, mTextPaint); + if (mStatus == STATUS_ERROR) { + drawErrorMsg(canvas, tip, 0); + } else { + //将提示语句放到正中间 + Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics(); + float textHeight = fontMetrics.top - fontMetrics.bottom; + float textWidth = mTextPaint.measureText(tip); + float pivotX = (mDisplayWidth - textWidth) / 2; + float pivotY = (mDisplayHeight - textHeight) / 2; + canvas.drawText(tip, pivotX, pivotY, mTextPaint); + } } else { float top; if (mPageMode == PageMode.SCROLL) { @@ -1224,6 +1240,22 @@ public abstract class PageLoader { } } + private void drawErrorMsg(Canvas canvas, String msg, float offset) { + float textInterval = mTextInterval + mTextPaint.getTextSize(); + Layout tempLayout = new StaticLayout(msg, mTextPaint, mVisibleWidth, Layout.Alignment.ALIGN_NORMAL, 0, 0, false); + List linesData = new ArrayList<>(); + for (int i = 0; i < tempLayout.getLineCount(); i++) { + linesData.add(msg.substring(tempLayout.getLineStart(i), tempLayout.getLineEnd(i))); + } + float pivotY = (mDisplayHeight - textInterval * linesData.size()) / 2f - offset; + for (String str : linesData) { + float textWidth = mTextPaint.measureText(str); + float pivotX = (mDisplayWidth - textWidth) / 2; + canvas.drawText(str, pivotX, pivotY, mTextPaint); + pivotY += textInterval; + } + } + //判断是不是d'hou private boolean isFirstLineOfParagraph(String line) { return line.length() > 3 && line.charAt(0) == (char) 12288 && line.charAt(1) == (char) 12288; @@ -1343,6 +1375,8 @@ public abstract class PageLoader { } else { dealLoadPageList(prevChapter); } + // 预加载上一页面 + preLoadPrevChapter(); return mCurChapter != null; } @@ -1404,7 +1438,8 @@ public abstract class PageLoader { boolean parseCurChapter() { // 解析数据 dealLoadPageList(mCurChapterPos); - // 预加载下一页面 + // 预加载上一页和下一页面 + preLoadPrevChapter(); preLoadNextChapter(); return mCurChapter != null; } @@ -1475,6 +1510,41 @@ public abstract class PageLoader { } } + // 预加载上一章 + private void preLoadPrevChapter() { + int prevChapter = mCurChapterPos - 1; + + // 如果不存在下一章,且下一章没有数据,则不进行加载。 + if (!hasPrevChapter() + || !hasChapterData(mChapterList.get(prevChapter))) { + return; + } + //如果之前正在加载则取消 + if (mPreLoadPrevDisp != null) { + mPreLoadPrevDisp.dispose(); + } + + //调用异步进行预加载加载 + Single.create((SingleOnSubscribe) e -> e.onSuccess(loadPageList(prevChapter))) + .compose(RxUtils::toSimpleSingle) + .subscribe(new SingleObserver() { + @Override + public void onSubscribe(Disposable d) { + mPreLoadPrevDisp = d; + } + + @Override + public void onSuccess(TxtChapter txtChapter) { + mPreChapter = txtChapter; + } + + @Override + public void onError(Throwable e) { + //无视错误 + } + }); + } + // 预加载下一章 private void preLoadNextChapter() { int nextChapter = mCurChapterPos + 1; @@ -1485,8 +1555,8 @@ public abstract class PageLoader { return; } //如果之前正在加载则取消 - if (mPreLoadDisp != null) { - mPreLoadDisp.dispose(); + if (mPreLoadNextDisp != null) { + mPreLoadNextDisp.dispose(); } //调用异步进行预加载加载 @@ -1495,7 +1565,7 @@ public abstract class PageLoader { .subscribe(new SingleObserver() { @Override public void onSubscribe(Disposable d) { - mPreLoadDisp = d; + mPreLoadNextDisp = d; } @Override diff --git a/app/src/main/res/layout/activity_search_book.xml b/app/src/main/res/layout/activity_search_book.xml index d04779d..1bdb144 100644 --- a/app/src/main/res/layout/activity_search_book.xml +++ b/app/src/main/res/layout/activity_search_book.xml @@ -1,52 +1,52 @@ - + + + - + android:layout_width="match_parent" + android:layout_height="60dp" + android:gravity="center" + android:orientation="horizontal" + android:paddingLeft="15dp" + android:paddingTop="10dp" + android:paddingRight="15dp" + android:paddingBottom="10dp"> + android:id="@+id/et_search_key" + android:layout_width="match_parent" + android:layout_height="35dp" + android:layout_weight="2" + android:background="@drawable/search_et_backcolor" + android:hint="输入关键词" + android:imeOptions="actionSearch" + android:paddingLeft="10dp" + android:textColor="@color/textPrimary" /> + android:id="@+id/tv_search_conform" + android:layout_width="match_parent" + android:layout_height="35dp" + android:layout_weight="8" + android:background="@drawable/search_btn_backcolor" + android:gravity="center" + android:text="搜索" + android:textColor="@color/textPrimaryInverted" + android:textSize="18sp" /> + + android:text="@string/all" + android:textColor="@color/textPrimary" + android:textSize="@dimen/text_small_size" /> + + android:text="@string/fuzzy_search" + android:textColor="@color/textPrimary" + android:textSize="@dimen/text_small_size" /> + android:text="@string/precise_search" + android:textColor="@color/textPrimary" + android:textSize="@dimen/text_small_size" /> + + android:id="@+id/rpb" + android:layout_width="match_parent" + android:layout_height="3dp" + android:visibility="visible" /> + android:id="@+id/ll_suggest_books_view" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:background="@color/colorForeground" + android:gravity="center" + android:orientation="vertical" + android:padding="5dp"> + android:id="@+id/tg_suggest_book" + style="@style/TagGroup" + android:layout_marginTop="5dp" + android:paddingStart="5dp" + android:paddingEnd="5dp" + app:atg_backgroundColor="@color/colorBackground" + app:atg_borderColor="@color/colorForeground" + app:atg_horizontalPadding="5dp" + app:atg_pressedBackgroundColor="@color/colorForeground" + app:atg_textColor="@color/textPrimary" + app:atg_textSize="14sp" + app:atg_verticalSpacing="5dp" /> + android:id="@+id/ll_refresh_suggest_books" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="8dp" + android:gravity="center" + android:orientation="horizontal"> + android:id="@+id/renew_image" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + app:srcCompat="@drawable/ic_refresh" + app:tint="@color/textPrimary" /> + android:id="@+id/renew_text" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="换一批" + android:textColor="@color/textPrimary" + android:textSize="14sp" /> @@ -138,62 +142,66 @@ + android:id="@+id/ll_history_view" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:background="@color/colorForeground" + android:gravity="center" + android:orientation="vertical" + android:padding="5dp"> + android:id="@+id/lv_history_list" + android:layout_width="match_parent" + android:layout_height="0dp" + android:layout_weight="1" + android:divider="@color/nothing" + android:fadingEdge="none" + android:overScrollMode="never" + android:scrollbars="none"> + + android:id="@+id/ll_clear_history" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:gravity="center" + android:orientation="horizontal"> + android:layout_width="20dp" + android:layout_height="20dp" + app:srcCompat="@drawable/ic_clear" + app:tint="@color/textPrimary" /> + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="清空历史记录" + android:textColor="@color/textPrimary" + android:textSize="14sp" /> + + + - + android:descendantFocusability="blocksDescendants"> + + android:layout_width="match_parent" + android:layout_height="wrap_content" /> + android:id="@+id/rv_search_books_list" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:padding="5dp" + android:visibility="visible" /> + android:id="@+id/fabSearchStop" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentEnd="true" + android:layout_alignParentBottom="true" + android:layout_marginEnd="30dp" + android:layout_marginBottom="30dp" + android:src="@drawable/ic_stop_black_24dp" + android:visibility="gone" + app:elevation="5dp" + app:fabSize="mini" + app:layout_anchorGravity="right|bottom" /> diff --git a/app/src/main/res/menu/menu_search.xml b/app/src/main/res/menu/menu_search.xml index 3dbf471..03c072d 100644 --- a/app/src/main/res/menu/menu_search.xml +++ b/app/src/main/res/menu/menu_search.xml @@ -1,7 +1,11 @@ - + 笔尖小说 言情楼 卧龙小说 + E文学 + 书海阁 + 落秋中文 + 三七中文 + 新笔趣阁 + 斋书苑 超星图书·实体 作品集·实体 99藏书·实体 @@ -337,6 +343,7 @@ 帮助 更新目录 完成 + 热搜 常亮 diff --git a/app/src/main/resources/crawler.properties b/app/src/main/resources/crawler.properties index 8f3b170..9280fb6 100644 --- a/app/src/main/resources/crawler.properties +++ b/app/src/main/resources/crawler.properties @@ -17,7 +17,7 @@ yunzhong=xyz.fycz.myreader.webapi.crawler.read.YunZhongReadCrawler sonovel=xyz.fycz.myreader.webapi.crawler.read.SoNovelReadCrawler quannovel=xyz.fycz.myreader.webapi.crawler.read.QuanNovelReadCrawler qiqi=xyz.fycz.myreader.webapi.crawler.read.QiQiReadCrawler -xs7=xyz.fycz.myreader.webapi.crawler.read.XS7ReadCrawler +xs7=xyz.fycz.myreader.webapi.crawler.read.XS7ReadCrawler2 du1du=xyz.fycz.myreader.webapi.crawler.read.Du1DuReadCrawler paiotian=xyz.fycz.myreader.webapi.crawler.read.PiaoTianReadCrawler laoyao=xyz.fycz.myreader.webapi.crawler.read.LaoYaoReadCrawler @@ -29,4 +29,10 @@ xiagu=xyz.fycz.myreader.webapi.crawler.read.XiaGuReadCrawler hongchen=xyz.fycz.myreader.webapi.crawler.read.HongChenReadCrawler bijian=xyz.fycz.myreader.webapi.crawler.read.BiJianReadCrawler yanqinglou=xyz.fycz.myreader.webapi.crawler.read.YanQingLouReadCrawler -wolong=xyz.fycz.myreader.webapi.crawler.read.WoLongReadCrawler \ No newline at end of file +wolong=xyz.fycz.myreader.webapi.crawler.read.WoLongReadCrawler +ewenxue=xyz.fycz.myreader.webapi.crawler.read.EWenXueReadCrawler +shuhaige=xyz.fycz.myreader.webapi.crawler.read.ShuHaiGeReadCrawler +luoqiu=xyz.fycz.myreader.webapi.crawler.read.LuoQiuReadCrawler +zw37=xyz.fycz.myreader.webapi.crawler.read.ZW37ReadCrawler +xbiquge=xyz.fycz.myreader.webapi.crawler.read.XBiQuGeReadCrawler +zaishuyuan=xyz.fycz.myreader.webapi.crawler.read.ZaiShuYuanReadCrawler \ No newline at end of file diff --git a/app/version_code.properties b/app/version_code.properties index 801ae8d..31d3f13 100644 --- a/app/version_code.properties +++ b/app/version_code.properties @@ -1,2 +1,2 @@ -#Wed Feb 03 13:23:18 CST 2021 -VERSION_CODE=181 +#Sat Feb 06 19:10:55 CST 2021 +VERSION_CODE=182