当前位置:AIGC资讯 > 数据采集 > 正文

快速入门手机爬虫

前言:
本人是在接触python爬虫后,萌发了“Android开发应该也能实现爬虫效果,这样用手机爬是不是会更方便”这一念想。于是兴趣使然就开始了手机爬虫的探索之旅。虽然这路已被探索无数次,但是对于未曾去过的我依旧向往。

一、整装待发:

1)爬虫工具和环境:

Android系统 Android studio

2)入手前准备:

了解kotlin语言:由于Android studio 4.1使用的是kotlin语言,所以需要自行稍微了解一下其语言特性,如定义方式、逻辑表达式,当然你会发现kotlin语言还是比较友好的。 了解线程和多线程 了解爬虫流程 了解数据长久化

二、地图浏览:

要实现如何手机爬虫,首先要知道爬虫的流程:
1)明确爬取目标
2)伪装访问
3)获取网页源码
4)提取出需要内容(常用手法:洗刷数据)
5)检验提取内容
6)爬取内容
7)爬取内容持久化

三、景点分析

<一>Jsoup使用

访问网页的手法有很多,如get、HttpClient 、HttpURLConnection等,但是我还是比较倾向于Jsoup。除了好用外,更多的是它和python的requests比较相似,所以用起来也比较顺手。

附上常用使用方法:

 var d:Document = Jsoup.connect("这里填写网页地址")
                        .userAgent("用户代理").get()
                

userAgent:获取方法参考https://jingyan.baidu.com/article/95c9d20d7bca17ec4e7561a4.html

坑点:
(1)这个方法需要配合线程使用,不然会报错。
(2)当地址是下载文件的地址时,可能会报org.jsoup.UnsupportedMimeTypeException: Unhandled content type Must be text/* ,处理手法是加入ignoreContentType函数

Jsoup.connect(strvideoUrl)
                        .userAgent("用户代理")
                        .ignoreContentType(true).get()
<二>常用伪装访问:

1)Jsoup.connect(strvideoUrl).userAgent(…)
2)Jsoup.connect(strvideoUrl).referrer(…)
3)Jsoup.connect(strvideoUrl).cookie(…)
注:括号内的…表示参数,因为懒所以就用…表示。用法类比python的request

<三>提取出需要内容:

利用Document类对象存储的内容进行提取。如何提取,可参考jsoup是如何选择指定元素的

个人极不推荐使用正则来洗刷数据,因为在Android里,正则的匹配率实在是低得感人,不好用。
推荐的手法是,先用Document的select和Elements的getElementsByAttribute函数进行筛选,在Document.select和Elements.getElementsByAttribute无法一步到位精准筛选到目标时,再考虑用Elements.attr()函数进行进一步筛选。

elementUrl.first().getElementsByAttribute("src")//利用属性的名称来定位

筛选数据常用到的:
1)Document.select
2)Elements.getElementsByAttribute
3)Elements.attr
4)Elements.removeAttr
5)Elements.replace

var elementTitle: Elements =d.select("[class*=\"video-title title-truncate m-t-5\"]")
//d为Document对象,获取方法如:var d:Document=Jsoup.connect("http://www.baidu.com/").get()

注:需要进行字符分割时,可以用String自带的split函数进行操作,比较便捷。

d.text().toString().split("#EXT-X-DISCONTINUITY")
<四>数据持久化

所谓的数据持久化,无非就是把数据保存下来,这一步无论在Python爬虫还是今天讲的Android爬虫,都是属于核心部分。下载手法有以下几种:

 1. 自己封装URLConnection 连接请求类
 2. Android自定的下载管理
 3. 使用第三方 okhttp 网络请求框架

具体说明参考:Android 文件下载三种基本方式

其实这三种方式,我都试过,最后因为便捷,所以选择了第二个下载方案:Android自定的下载管理。因为这个下载方案是调用了现有的下载框架进行下载,减轻了许多代码量。

优点: 会在notification 显示下载的进度,同时可以暂停、重新连接。

使用手法:

   //创建下载任务,downloadUrl就是下载链接
    val request = DownloadManager.Request(Uri.parse(strvideodownloadUrl[i]))
    //指定下载路径和下载文件名
    request.setDestinationInExternalPublicDir("", "/storage/"+strTitle+'/')
    //获取下载管理器
    val downloadManager = getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
    //将下载任务加入下载队列,否则不会进行下载
    downloadManager.enqueue(request)
    println(i.toString()+".ts"+"已完成"+'\n')

与Python对比:
在Python中下载一般都是使用多线程调用函数下载,但是 “自定的下载管理” 这种下载方案使Android爬虫的下载方式具有一定的先天优势。

Okey,到这里其实整个Android爬虫就讲完了,是不是觉得很简单呢。摸索的过程比较曲折,但是也比较有趣。最后给出本文的另一核心重点–视频合并。

<五>视频合并

网上爬下来的视频文件一般都是ts文件居多,当然Android是能播放ts文件的,但是一百或几百个ts,一个个播放这也是需要相当的耐心,那合并成一个mp4文件是不是众望所归?Python可以通过调用”copy /b“指令进行ts文件合并,那Android是如何把多个ts文件合并成一个文件呢?

想必很多人在网上搜索过,但是多数搜索到的是使用软件进行合并,但是作为一个开发爱好者,还是想自己的软件能自实现合并。

val fos = FileOutputStream(realFile)  //fos承载的是输出文件
 var file:File =File("/storage/emulated/0/storage/"+strTitle+'/'+"video"+strnum+".ts")

  if (file.exists()){
      var fis=FileInputStream(file)
      var tmpBytes = ByteArray(fis.available())
      var length = tmpBytes.size
      println(length)
      if(i==0){
          while(fis.read(tmpBytes)!=-1){
              fos.write(tmpBytes,0,length)
          }
      }
      //之后的文件,去掉头文件就可以了.amr格式的文件的头信息为 6字节
      //当然去不去这6字节都是能合并的,合并出来的文件也能正常播放
      else{
          while(fis.read(tmpBytes)!=-1){
              fos.write(tmpBytes,6,length-6)
          }
      }
      fos.flush()
      fis.close()
 }

后感: 经过Android爬虫之旅后,感觉还是Python比较强大。

到此,全文已完结。文笔不好,将就看看。如果本文能让你学到东西,希望能点个赞。

成果展示:


点击”案例展示“按钮访问目标地址并开始下载


下载完成后,点击下方”等待下载完毕后点击下载“(打错字,改成合并囧)按钮,然后就会合并ts文件,并删除ts文件

更新时间 2023-11-08