Python爬取當貝市場APK應用信息並下載

年初自學python一段時間,項目中很少遇到需要實踐python的地方,最近公司機頂盒的應用市場需要進行應用掛網,測試同事需要從當貝市場和奇珀市場下載特定的200多個應用,並提取信息掛到自己的服務器上,作爲客戶端開發的我,能用程序實現的絕對不會使用重複勞動力。

安裝python 3.7,針對爬蟲程序依賴的module,以管理員身份啓動cmd
所需模塊:beautifulsoup4 處理網頁解析
requests 處理網頁請求
re 處理正則表達式
lxml 是python的一個解析庫,支持HTML和XML的解析
lxml需要自己下載:https://www.lfd.uci.edu/~gohlke/pythonlibs/
使用pip install <模塊>即可。

如下圖,需要抓取應用名稱,版本,簡介和圖片並下載。
在這裏插入圖片描述
chrome F12後可以看到相應標籤的class等屬性,右鍵-copy-copy selector就可以複製css選擇器標籤元素。
關鍵代碼如下:

def downloadApp(AppName):
    url = 'http://www.dangbei.com/app/plus/search.php?kwtype=0&q=' + AppName

    # 獲取網頁源碼
    web_data = requests.get(url, headers=headers)
    # print('content:' + web_data.text)
    # 解析網頁
    soup = BeautifulSoup(web_data.text, 'lxml')

    try:
        # 獲取第一個搜索內容的名字
        firstRecordName = soup.select('#softList > li:nth-of-type(1) > div > div.softInfo > p.title > a')[
            0].get_text().strip()

        if AppName in firstRecordName:
            # 正則表達式找出擡頭與紅色關鍵詞之間的跳轉鏈接文本
            # 正則表達式的運用可以參考這篇博客: https://www.cnblogs.com/chuxiuhong/p/5885073.html
            pattern0 = re.compile(r'<a href=".+' + "<font color='red'>")
            linkUrls = pattern0.findall(web_data.text)
            # print(linkUrls[0])
            # 獲取二級頁面鏈接  http://www.dangbei.com/app/tv/2015/0723/2687.html變爲https://m.dangbei.com/wap-view-2687.html
            tempStr = linkUrls[0].split()[1].split('"')[1]
            tempList = re.findall(r'\d+', tempStr)
            linkUrl = 'https://m.dangbei.com/wap-view-' + tempList[2] + ".html"
            print("'" + firstRecordName + "'" + "的應用頁面:" + linkUrl)

            # 進入二級頁面,以獲取應用詳情
            web_data = requests.get(linkUrl, headers=headers)
            soup = BeautifulSoup(web_data.text, 'lxml')
            try:
                version = soup.select('div.app-cat > span:nth-of-type(4)')[0].get_text().strip()
                version = version.split(':')[1]
                print("'" + firstRecordName + "'" + "的版本號:\n" + version)
                filename = AppName + '_' + version
                appdir = os.path.join(PATH, filename)
                isExists = os.path.exists(appdir)
                if not isExists:
                    # 創建文件夾
                    print('新建了一個', filename, '的文件夾!')
                    os.makedirs(appdir)
                    # 切換工作路徑到AppName下
                    os.chdir(appdir)
                else:
                    print(filename, '文件夾已經存在了!')
                    # if shutil.rmtree(appdir, True):
                    # os.rmdir(appdir)  # 只能刪除空目錄,否則報錯
                    os.chdir(appdir)
                    return
                introduction = soup.select('div.info-content > div > p')[0].get_text()
                print("'" + firstRecordName + "'" + "的詳情介紹:\n" + introduction)
                # 'w'或者'wb'表示寫文本文件或寫二進制文件
                with open(filename + '.txt', 'w', encoding='utf-8') as f:
                    f.write(introduction)
                photourl = soup.select('div.scroll_box > ul > li')
                print("'" + firstRecordName + "'" + "的圖片地址:")
                count = 1
                for temp in photourl:
                    temp_url = temp.find('img')['src']
                    temp_url = 'http://' + temp_url.split('//')[1]
                    large_url = temp_url.split('!')[0]
                    print(large_url)
                    urllib.request.urlretrieve(large_url,  'large_%s.jpg' % count)
                    urllib.request.urlretrieve(temp_url, 'small_%s.jpg' % count)
                    count += 1
                apk = soup.select('div.info_downxload > a.btn_download_app')[0]
                apkurl = apk.attrs['href']
                apktitle = apk.attrs['title']
                print("'" + firstRecordName + "'" + "的下載鏈接:\n" + apkurl)
                urllib.request.urlretrieve(apkurl, apktitle + '_' + version + '.apk')
            except:
                print('search error')
                os.chdir(PATH)
                with open('record.txt', 'a+', encoding='utf-8') as f:
                    f.write(AppName + '\n')
        else:
            print("未找到與'" + AppName + "'相關的內容")
            os.chdir(PATH)
            with open('record.txt', 'a+', encoding='utf-8') as f:
                f.write(AppName + '\n')

    except:
        print("未找到與'" + AppName + "'相關的內容")
        os.chdir(PATH)
        with open('record.txt', 'a+', encoding='utf-8') as f:
            f.write(AppName + '\n')

抓取結果如圖:
在這裏插入圖片描述
在這裏插入圖片描述

大致使用:applist.txt輸入需要抓取的應用名稱,若有搜索結果便新建一個應用文件夾,裏面存放圖片和apk等信息,由於抓取的信息需要存放在對應目錄,採用線程池並行下載會存在文件存放錯亂的問題,所以採用串行下載。
期間遇到的問題:

  1. 複製的selector的若包含nth-child,得到的結果是空,使用nth-of-type即可。兩者區別: nth-of-type(n) 匹配屬於父元素的特定類型的第 N 個子元素的每個元素,nth-child(n)選取父元素的第 N 個子元素,與類型無關。
  2. os.rmdir只能刪除空目錄,否則報錯;shutil.rmtree() 可遞歸刪除文件夾下的所有子文件夾和子文件。
  3. 讀寫文件,記得統一編碼,比如encoding=‘utf-8’。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章