歡迎光臨
每天分享高質量文章

利用爬蟲將電影網站打包成一個APP

來自:看雪論壇,作者: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 = '