來自:看雪論壇,作者:wushaominkk
https://bbs.pediy.com/thread-246396.htm
以前總是透過HDMI線將電腦連線電視看劇看電影,但是每次想快進啊進行一些操作過於麻煩,手機上的APP的資源又太少,於是想到將電影網站打包成一個APP!
APP已經差不多做好了,最近也比較忙,沒什麼時間去弄,介面很醜,這裡我講講我的主要思路,自己動手才有樂趣!
在做之前整理下思路,怎樣才能把網站搬到APP上呢?
有兩個方法:
1.透過WebView簡單粗暴
將整個網站搬過來,幾十行程式碼搞定!但是使用者體驗不是很好、廣告多、字型小、操作也不是很方便。
2.利用爬蟲,需要什麼爬什麼!然後將資料顯示在自己做的介面上!
Let’go
首先我們搭一個介面大概的介面出來。
[Java]純文字檢視複製程式碼
ButterKnife.bind(this);
mTabBar.init(getSupportFragmentManager())
.setImgSize(50, 50)
.setFontSize(10)
.setTabPadding(4, 6, 10)
.setChangeColor(Color.RED, Color.DKGRAY)
.addTabItem("首頁", R.mipmap.ic_launcher_round, HomeFragment.class)
.addTabItem("電影", R.mipmap.ic_launcher_round, MoveFragment.class)
.addTabItem("電視劇", R.mipmap.ic_launcher_round, TVplayFragment.class)
.addTabItem("動漫", R.mipmap.ic_launcher_round, CartoonFragment.class);
一個4個Fragment系結一個activity,每個fragment。
上面是個recyclerview,底部是BottomTabBar。
介面搭好了就差資料了
匯入圖片載入和網路請求依賴
compile ‘com.squareup.picasso:picasso:2.5.2’
compile ‘com.mcxiaoke.volley:library:1.0.19’開啟網站,F12檢視當前網頁原始碼,找到需要的資料
首先透過網路請求獲取整個頁面資料,然後正則匹配找到我們需要的資料、圖片、連結、標題和評分,新建一個Bean類將資料儲存到裡面。
[Java]純文字檢視複製程式碼
public class DataBean {
private String DataName;
private String DataScore;
private String DataImg;
private String DataNetWork;
public String getDataName() {
return DataName;
}
public void setDataName(String dataName) {
DataName = dataName;
}
public String getDataScore() {
return DataScore;
}
public void setDataScore(String dataScore) {
DataScore = dataScore;
}
public String getDataImg() {
return DataImg;
}
public void setDataImg(String dataImg) {
DataImg = dataImg;
}
public String getDataNetWork() {
return DataNetWork;
}
public void setDataNetWork(String dataNetWork) {
DataNetWork = dataNetWork;
}
}
透過recyclerView將資料顯示到介面上,透過介面回呼設定點選事件點選圖片跳轉到詳情頁
[Java]純文字檢視複製程式碼
RequestQueue queue = Volley.newRequestQueue(getActivity());
MyStringRequest stringRequest = new MyStringRequest(getHosturl(), new Response.Listener() {
@Override
public void onResponse(String response) {
String regEx = " ";
Pattern pattern = Pattern.compile(regEx);
mMatcher = pattern.matcher(response);
if (mData != null) {
mData.clear();
}
new Thread(new Runnable() {
@Override
public void run() {
while (mMatcher.find()) {
//Log.e(TAG, matcher.group());
/*Log.e(TAG, mMatcher.group(1));
Log.e(TAG, mMatcher.group(2));
Log.e(TAG, mMatcher.group(3));
Log.e(TAG, mMatcher.group(4));*/
DataBean dataBean = new DataBean();
dataBean.setDataNetWork(mMatcher.group(1));
dataBean.setDataImg(mMatcher.group(2));
dataBean.setDataName(mMatcher.group(4));
dataBean.setDataScore(mMatcher.group(3));
mData.add(dataBean);
}
}
}).start();
if (mHomeAdapter == null) {
mHomeAdapter = new homeAdapter(getContext(), mData, mGridLayoutManager);
}
mRecyclerView.setAdapter(mHomeAdapter);
mHomeAdapter.notifyDataSetChanged();
mTvThisPage.setText("第"+mThisPage+"頁");
Toast.makeText(getContext(), "第" + mThisPage + "頁", Toast.LENGTH_SHORT).show();
mHomeAdapter.setItemClickListener(new homeAdapter.OnItemClickListener() {
@Override
public void onItemClick(int position) {
String url = mData.get(position).getDataNetWork();
String title = mData.get(position).getDataName();
String img_url = mData.get(position).getDataImg();
String requestUrl = getHosturl() + url;
//Toast.makeText(getContext(), requestUrl, Toast.LENGTH_SHORT).show();
Intent intent = new Intent(getContext(), DetailsActivity.class);
intent.putExtra("title", title);
intent.putExtra("img_url", img_url);
intent.putExtra("requestUrl", requestUrl);
startActivity(intent);
}
});
//Log.e(TAG, response);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
為了便於維護將首頁封裝成基類,然後將電影、電視劇和動漫頁面繼承,稍加改動,這樣4個頁面就出來了。
[Java]純文字檢視複製程式碼
public class MoveFragment extends HomeFragment implements View.OnClickListener {
@Override
protected void intitView() {
hostUrl = "http://m.yiybb.com/dianying/";
super.intitView();
mThisPage = 1;
listTpye = "List_15_";
mTvThisPage.setVisibility(View.VISIBLE);
}
@Override
protected void initData() {
super.initData();
}
@Override
protected String setTitle() {
return "電影";
}
@Override
protected void setViibilly() {
page.setVisibility(View.VISIBLE);
}
第二大步:
然後我們來做詳情頁
透過Intent獲取到上個頁面傳遞過來的URL,圖片連結和標題,透過URL獲取整個頁面資料,然後正則匹配,其他需要的資料。
[Java]純文字檢視複製程式碼
RequestQueue queue = Volley.newRequestQueue(this);
MyStringRequest stringRequest = new MyStringRequest(mRequestUrl, new Response.Listener() {
@Override
public void onResponse(String response) {
//Log.e(TAG, response );
String regEx = "(.+?) ";
/*
*/
Pattern pattern = Pattern.compile(regEx);
mMatcher = pattern.matcher(response);
new Thread(new Runnable() {
@Override
public void run() {
while (mMatcher.find()) {
//Toast.makeText(DetailsActivity.this, mMatcher.group() + "", Toast.LENGTH_SHORT).show();
//Log.e(TAG, mMatcher.group());
//Log.e(TAG, mMatcher.group(1));
//Log.e(TAG, mMatcher.group(2));
String url = mMatcher.group(1);
String title = mMatcher.group(2);
//Log.e(TAG, mMatcher.group(3));
//Log.e(TAG, mMatcher.group(4));
DetailsBean dataBean = new DetailsBean();
dataBean.setTitle(title);
dataBean.setUrl(url);
mData.add(dataBean);
}
}
}).start();
DetailAdapter adapter = new DetailAdapter(DetailsActivity.this,mData,mGridLayoutManager);
mDaRecyView.setAdapter(adapter);
adapter.setItemClickListener(new DetailAdapter.OnItemClickListener() {
@Override
public void onItemClick(int position) {
String url = "http://m.yiybb.com/"+mData.get(position).getUrl();
Intent intent = new Intent(DetailsActivity.this,PlayActivity.class);
intent.putExtra("url",url);
startActivity(intent);
}
});
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e(TAG, error.getMessage(), error);
Toast.makeText(DetailsActivity.this, "網路不穩定!", Toast.LENGTH_SHORT).show();
}
});
queue.add(stringRequest);
}
第三大步:
最重要就是播放頁面了,這裡費了點時間。
剛開始我也是按照前2步驟去操作,但是發現怎麼都爬不到獲取不到連結開啟原網站才發現播放連結是動態載入的而且還3層加密了!MMP
開啟播放頁面,F12選擇sources,檢視原始碼:
繼續看原始碼找script標簽看下裡面做了什麼:
<script language="javascript">var StrHtml;var url=set_code(unescape("JN0HT%250G%256B%256BJeN.Ty6l.167%256Bx%256BlDvoVW%256B1dTw8xE.mkyw",0,0));var nexturl="no";var nextpath="no";var Player={Url:url,Height:240,Width:600,Show:null};function $ShowPlayer(w,h){document.write($Showhtml());}script>
<script language=“javascript” src=“Play/23.js”>script><script language=“javascript”>$ShowPlayer(600,240);script>
JN0HT%250G%256B%256BJeN.Ty6l.167%256Bx%256BlDvoVW%256B1dTw8xE.mkyw 是第一加密後的連結。至於怎麼來的,我們不管他,這個資料是可以爬出來的。
unescape()方法是JS自帶解密方法。
set_code()再次加密
找到了主要的邏輯,順著思路往下走,在netWork掃清頁面看下載入了那些東西,主要看js,發現載入了這麼幾個東東。
一個個檢視吧,裡面搜尋set_code這個方法
找到了set_code方法:
大概看了下,裡面又呼叫了____e() 和 ____d()
以為這樣就找到了連結,我剛開始也這麼覺得,但是在網頁上開啟還是錯誤的
繼續回到sources,檢視原始碼:
這個才是主要動態載入標簽的主要邏輯,在原始碼了找到Play/23.js
function $ShowPlayer(width,height){
StrHtml = '';
document.write(StrHtml);
}
將之前加密的URL再一次拼接!
找到了加密方法,那我們來做一個工具類將其解密。
[HTML]純文字檢視複製程式碼
var StrHtml;
function ____e(){
return"0123456789,ABCDEFG,HIJKLMN,OPQRST,UVWXYZ,abcdefg,hijklmn,opqrst,uvwxyz"
}
function ____d(){
return"4560123987,GFEDCBA,MHIJLNK,PQRSTO,ZUVWXY,gfedcba,mhijlnk,pqrsto,zuvwxy"
}
function set_code(s,en,isN){
var e_s = en?____e():____d(), d_s = en?____d():____e(),str="";
e_s=isN?e_s.split(",")[0]:e_s,d_s=isN?d_s.split(",")[0]:d_s;
for(var i=0;i
n=-1;n=e_s.indexOf(s.charAt(i));
if(n!=-1){
str+=d_s.charAt(n)
}else{
str+=s.charAt(i)
}
}
return str
};
function getUrl(first_url){
var url = set_code(unescape(first_url, 0, 0));
StrHtml="http://m.yiybb.com/ck/ck.html?" +url+ "|";
window.open(StrHtml);
}
接下來將HTML放到asset/index.html
[zava]純文字檢視複製程式碼
mWebView.loadUrl("file:///android_asset/index.html");
WebSettings settings = mWebView.getSettings();
settings.setJavaScriptEnabled(true);
mWebView.addJavascriptInterface(this, "android");
mWebView.setWebChromeClient(webChromeClient);
mWebView.setWebViewClient(mWebViewClient);
settings.setDomStorageEnabled(true);
這樣就可以透過webView與本地的HTML檔案互動,
接下來獲取到播放頁面第一次加密的連結,
[Java]純文字檢視複製程式碼
RequestQueue queue = Volley.newRequestQueue(this);
MyStringRequest stringRequest = new MyStringRequest(mUrl, new Response.Listener
() { @RequiresApi(api = Build.VERSION_CODES.KITKAT)
@Override
public void onResponse(String response) {
Log.d(TAG, response);
String regEx = "unescape\("(.+?)",0,0\)";
Pattern pattern = Pattern.compile(regEx);
mMatcher = pattern.matcher(response);
new Thread(new Runnable() {
@Override
public void run() {
while (mMatcher.find()) {
Log.e(TAG, mMatcher.group(1));
mFirst_url = mMatcher.group(1);
final String requestUrl = "javascript:getUrl('"+mFirst_url+"')";
Log.e(TAG, requestUrl );
mWebView.post(new Runnable() {
@Override
public void run() {
mWebView.loadUrl(requestUrl);
}
});
}
}
}).start();
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e(TAG, error.getMessage(), error);
Toast.makeText(PlayActivity.this, "網路不穩定!載入失敗!請稍後重試!", Toast.LENGTH_SHORT).show();
}
});
queue.add(stringRequest);
}
呼叫html自己寫的工具類getUrl方法,將獲取到的引數傳進去,然後再載入網頁。
大功告成!
●編號694,輸入編號直達本文
●輸入m獲取文章目錄
Linux學習
更多推薦《18個技術類公眾微信》
涵蓋:程式人生、演演算法與資料結構、駭客技術與網路安全、大資料技術、前端開發、Java、Python、Web開發、安卓開發、iOS開發、C/C++、.NET、Linux、資料庫、運維等。