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’。

猜你喜欢

转载自blog.csdn.net/qq_23069607/article/details/83038795