爬取排行榜应用信息

爬取豌豆荚排行榜app信息
- app_detail_url - 应用详情页url
- app_image_url - 应用图片url
- app_name - 应用名称
- app_install_count - 下载量
- app_size - 应用大小
- app_info - 应用简介 1.分析:
- 目标url: https://www.wandoujia.com/top/app - 在网页中,发现了加载更多按钮,点击后,为异步请求,请求url为:
https://www.wandoujia.com/wdjweb/api/top/more?resourceType=0&page=2&ctoken=kuoxO3QZz7JKIJtuA6RXibwL - 修改page的值,可以得到响应数据,则可以直接爬接口数据,page范围为1~41 2. 爬取数据过程
- 发送请求
- 解析数据
- 保存数据到MySQL数据库

代码

# top_app.py
import requests
from bs4 import BeautifulSoup
from wandoujia.mysql_control import MySQL # 请求函数
def get_data(url):
response = requests.get(url)
return response.json().get('data') # 解析数据
def parse_data(json_data):
data = json_data.get('content')
# print(data)
soup = BeautifulSoup(data, 'lxml') # 找出所以的li标签(每个app都在一个li标签里)
li_list = soup.find_all(name='li', attrs={'class': 'card'})
# print(li_list) for li in li_list:
# 获取app详情页url
app_detail_url = li.find(name='a').get('href')
# print('应用详情页:', app_detail_url) # 获取app图片url
img_tag = li.find(name='img')
# print(img_tag)
# app图片url
app_image_url = img_tag.get('data-original')
# print('应用图片:', app_image_url)
# 应用名称
app_name = img_tag.get('alt')
# print('应用名称:', app_name) # 获取应用下载量
app_install_count = li.find(name='span', attrs={'class': 'install-count'}).text
# print('应用下载量:', app_install_count) # 获取应用大小
try:
app_size = li.find(name='span', attrs={'title': re.compile('MB')}).text
except:
app_size = ''
# print('应用大小:', app_size) # 获取应用简介
app_info = li.find(name='div', attrs={'class': 'comment'}).text.strip()
# print('应用简介:', app_info)
yield app_detail_url, app_image_url, app_name, app_install_count, app_size, app_info # 保存数据
def save_data(generator_data, mysql_obj):
for data in generator_data:
# print(data) sql = 'insert into top_app(app_detail_url, app_image_url, app_name, app_install_count, app_size, app_info) ' \
'values(%s, %s, %s, %s, %s, %s)' mysql_obj.execute(sql, data) print(f'{data[2]} 数据已爬取成功')
print('*' * 100) if __name__ == '__main__':
# 实例化数据库对象
mysql_obj = MySQL() # 拼接url
for page in range(1, 42):
url = f'https://www.wandoujia.com/wdjweb/api/top/more?resourceType=0&page={page}&ctoken=kuoxO3QZz7JKIJtuA6RXibwL' # 发送请求
json_data = get_data(url)
# 解析数据
generator_data = parse_data(json_data)
# 保存数据
save_data(generator_data, mysql_obj)

MySQL数据库

# mysql.py
import pymysql class MySQL:
def __init__(self):
self.client = pymysql.connect(
host='127.0.0.1',
port=3306,
database='wandoujia',
user='root',
password='admin',
charset='utf8',
autocommit=True
) self.cursor = self.client.cursor(pymysql.cursors.DictCursor) def execute(self, sql, args):
try:
self.cursor.execute(sql, args)
except Exception as e:
print(e) def close(self):
self.cursor.close()
self.client.close()

爬取详情页下载链接并下载

爬取豌豆荚排行榜app详情页

- 分析:
- 目标url:在top_app文件中已有爬取的函数,可直接使用得到app_detail_url - 详情页面分析:
- <div class="download-wp">下存在a标签<a class="normal-dl-btn">,href属性为下载链接 - 爬取数据过程:
- 使用上面top_app.py中的get_data(),和parse_data()可得到每个app的详情页
- 发送请求
- 解析数据
- 多线程下载app

代码

# top_app_detail.py
import os
from concurrent.futures import ThreadPoolExecutor
import requests
from bs4 import BeautifulSoup
from wandoujia import top_app # 获取详情页数据
def get_detail_data(data):
response = requests.get(data[0])
# print(response.text)
return response.text # 解析数据
def parse_detail_data(response):
soup = BeautifulSoup(response, 'lxml')
app_download_url = soup.find(name='a', attrs={'class': 'normal-dl-btn'}).get('href')
# print(f'应用名称: {data[2]}, 下载链接: {app_download_url}') return data[2], app_download_url # 保存数据
def download_app(app_name_download_url_tuple):
# 下载app
app_name = os.path.join(save_dir, app_name_download_url_tuple[0])
print(app_name_download_url_tuple[0], '开始下载')
app_file = requests.get(app_name_download_url_tuple[1])
# print(app_name)
with open(app_name, 'wb') as f:
for line in app_file.iter_lines():
f.write(line) print(app_name_download_url_tuple[0], '下载完成') if __name__ == '__main__':
# app保存文件夹
save_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'top_app')
# 多线程下载,下载线程数为3
pool = ThreadPoolExecutor(3) # 拼接url
for page in range(1, 42):
url = f'https://www.wandoujia.com/wdjweb/api/top/more?resourceType=0&page={page}&ctoken=kuoxO3QZz7JKIJtuA6RXibwL' # 获取详情页url
# 发送请求
json_data = top_app.get_data(url)
# 解析数据
generator_data = top_app.parse_data(json_data) # 爬取详情页
for data in generator_data:
# print(data)
# 获取详情页数据
detail_response = get_detail_data(data)
# 解析详情页数据
app_name_download_url_tuple = parse_detail_data(detail_response) # 单线程请求并下载app
# download_app(app_name_download_url_tuple) # 使用多线程请求并下载app,下载线程数不宜过多,否则会很慢
pool.submit(download_app, app_name_download_url_tuple)

requests+bs4爬取豌豆荚排行榜及下载排行榜app的更多相关文章

  1. requests + bs4 爬取豌豆荚所有应用的信息

    1.分析豌豆荚的接口的规律 - 获取所有app的接口url 2.往每一个接口发送请求,获取json数据 解析并提取想要的数据 app_data: 1.图标 app_img_url 2.名字 app_n ...

  2. requests bs4 爬取 资讯 图片

    #!/usr/bin/env python # Version = 3.5.2 # __auth__ = '无名小妖' import requests from bs4 import Beautifu ...

  3. PYTHON 爬虫笔记八:利用Requests+正则表达式爬取猫眼电影top100(实战项目一)

    利用Requests+正则表达式爬取猫眼电影top100 目标站点分析 流程框架 爬虫实战 使用requests库获取top100首页: import requests def get_one_pag ...

  4. 使用request+bs4爬取所有股票信息

    爬取前戏 我们要知道利用selenium是非常无敌的,自我认为什么反爬不反爬都不在话下,但是今天我们为什么要用request+bs4爬取所有股票信息呢?因为他比较原始,因此今天的数据,爬取起来也是比较 ...

  5. [实战演练]python3使用requests模块爬取页面内容

    本文摘要: 1.安装pip 2.安装requests模块 3.安装beautifulsoup4 4.requests模块浅析 + 发送请求 + 传递URL参数 + 响应内容 + 获取网页编码 + 获取 ...

  6. python实战项目 — 使用bs4 爬取猫眼电影热榜(存入本地txt、以及存储数据库列表)

    案例一: 重点: 1. 使用bs4 爬取 2. 数据写入本地 txt from bs4 import BeautifulSoup import requests url = "http:// ...

  7. requests+正则爬取豆瓣图书

    #requests+正则爬取豆瓣图书 import requests import re def get_html(url): headers = {'User-Agent':'Mozilla/5.0 ...

  8. requests+正则表达式爬取ip

    #requests+正则表达式爬取ip #findall方法,如果表达式中包含有子组,则会把子组单独返回出来,如果有多个子组,则会组合成元祖 import requests import re def ...

  9. 爬虫系列4:Requests+Xpath 爬取动态数据

    爬虫系列4:Requests+Xpath 爬取动态数据 [抓取]:参考前文 爬虫系列1:https://www.cnblogs.com/yizhiamumu/p/9451093.html [分页]:参 ...

随机推荐

  1. 2021.8.13考试总结[NOIP模拟38]

    T1 a 入阵曲.枚举矩形上下界,之后从左到右扫一遍.用树状数组维护前缀和加特判可以$A$,更保险要脸的做法是双指针扫,因为前缀和单调不减. $code:$ 1 #include<bits/st ...

  2. [CSP-S2021] 回文

    链接: P7915 题意: 给出一个长度为 \(2n\) 的序列 \(a\),其中 \(1\sim n\) 每个数出现了 2 次.有 L,R 两种操作分别是将 \(a\) 的开头或末尾元素加入到初始为 ...

  3. VUE项目实现主题切换

    需求是 做一个深色主题和浅色主题切换的效果 方法一 多套css 这个方法也是最简单,也是最无聊的. <!-- 中心 --> <template> 动态获取父级class名称,进 ...

  4. Centos 7 端口聚合

    简单粗暴,直接复制命令就好了 还是先啰嗦一下,添加网卡之后,如果没有网卡配置文件,可以通过nmcli con show 先查看网卡的唯一ID,然后复制其他的网卡配置文件,修改device项,name项 ...

  5. Java测试开发--HttpClient常规用法(九)

    1.HttpClient可以读取网页(HTTP/HTTPS)内容 2.对url发送get/post请求(带不带参数都可以),进行测试 一.maven项目pom.xml需要引入包 <depende ...

  6. Java oop三大特性(封装,继承,多态)

    封装 顾名思义,就是将数据封装起来,提高数据的安全性.我们程序都是要追求"高内聚,低耦合".高内聚就是类的内部数据操作细节自己完成,不允许外部干涉,低耦合:仅暴露少量的方法给外部使 ...

  7. idea断点调试

    基本使用 1 show execution point (Alt+F10):跳转到断点所执行的地方,也就是说你在看代码的时候,点到其他地方,一点这个按钮,就到了程序执行到当前哪行的代码的地方. 2 s ...

  8. 多线程 | 03 | CAS机制

    Compare and swap(CAS) 当前的处理器基本都支持CAS,只不过每个厂家所实现的算法并不一样罢了,每一个CAS操作过程都包含三个参数:一个内存地址V,一个期望的值A和一个新值B,操作的 ...

  9. v-html | 数据内容包含元素标签或者样式

    问题 如果我们展示的数据包含元素标签或者样式,我们想展示标签或样式所定义的属性作用,该怎么进行渲染 插值表达式{{}}和v-text指令被直接解析为了字符串元素. <body> <d ...

  10. node获取请求我的客户端的地址

    node获取请求我的客户端的地址 const http = require('http'); //创建 Server const server = http.createServer() // 监听r ...