1、BeautifulSoup 解析库
2、MongoDB 存储库
3、requests-html 请求库
BeautifulSoup
1、什么bs4,为什么要使用bs4?
是一个基于re开发的解析库,可以提供一些强大的解析功能。
提高提取数据的效率与爬虫开发效率。
2、安装与使用
pip3 install beautifulsoup4 # 安装bs4
pip3 install lxml # 下载lxml解析器
MongoDB 非关系型数据库
一 安装与使用
1、下载安装
https://www.mongodb.com/download-center/community
2、在C盘创建一个data/db文件夹
- 数据的存放路径
3、mongod启动服务
进入终端,输入mongod启动mongoDB服务。
4、mongo进入mongoDB客户端
打开一个新的终端,输入mongo进入客户端
二 数据库操作
数据库操作:
切换库:
SQL:
use admin; 有则切换,无则报错。
MongoDB:
use tank; 有则切换,无则创建,并切换tank库中。
查数据库:
SQL:
show databases;
MongoDB:
show dbs;
显示的数据库若无数据,则不显示。
删除库:
SQL:
drop database
MongoDB:
db.dropDatabase()
集合操作: MySQL中叫做表。
创建集合:
SQL:
create table f1, f2...
MongoDB:
# 在当前库中通过.来创建集合
db.student
插入数据:
# 插入多条数据
db.student.insert([{"name1": "tank1"}, {"name2": "tank2"}])
# 插入一条
db.student.insert({"name": "tank"})
查数据:
# 查找student集合中所有数据
db.student.find({})
# 查一条 查找name为tank的记录
db.student.find({"name":"tank"})
三 python链接MongoDB
1、下载第三方模块pymongo
pip3 install pymongo
2、链接mongoDB客户端
client = MongoClient('localhost', 27017)
1 '''''' 2 ''' 3 pip3 install beautifulsoup4 # 安装bs4 4 pip3 install lxml # 下载lxml解析器 5 ''' 6 html_doc = """ 7 <html><head><title>The Dormouse's story</title></head> 8 <body> 9 <p class="sister"><b>$37</b></p> 10 <p class="story" id="p">Once upon a time there were three little sisters; and their names were 11 <a href="http://example.com/elsie" class="sister" >Elsie</a>, 12 <a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and 13 <a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>; 14 and they lived at the bottom of a well.</p> 15 16 <p class="story">...</p> 17 """ 18 19 # 从bs4中导入BeautifulSoup 20 from bs4 import BeautifulSoup 21 22 # 调用BeautifulSoup实例化得到一个soup对象 23 # 参数一: 解析文本 24 # 参数二: 25 # 参数二: 解析器(html.parser、lxml...) 26 soup = BeautifulSoup(html_doc, 'lxml') 27 28 print(soup) 29 print('*' * 100) 30 print(type(soup)) 31 print('*' * 100) 32 # 文档美化 33 html = soup.prettify() 34 print(html) 35 36 37 38 39 40 html_doc = """<html><head><title>The Dormouse's story</title></head><body><p class="sister"><b>$37</b></p><p class="story" id="p">Once upon a time there were three little sisters; and their names were<b>tank</b><a href="http://example.com/elsie" class="sister" >Elsie</a>,<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;and they lived at the bottom of a well.<hr></hr></p><p class="story">...</p>""" 41 42 from bs4 import BeautifulSoup 43 soup = BeautifulSoup(html_doc, 'lxml') 44 45 ''' 46 遍历文档树: 47 1、直接使用 48 2、获取标签的名称 49 3、获取标签的属性 50 4、获取标签的内容 51 5、嵌套选择 52 6、子节点、子孙节点 53 7、父节点、祖先节点 54 8、兄弟节点 55 ''' 56 57 # 1、直接使用 58 print(soup.p) # 查找第一个p标签 59 print(soup.a) # 查找第一个a标签 60 61 # 2、获取标签的名称 62 print(soup.head.name) # 获取head标签的名称 63 64 # 3、获取标签的属性 65 print(soup.a.attrs) # 获取a标签中的所有属性 66 print(soup.a.attrs['href']) # 获取a标签中的href属性 67 68 # 4、获取标签的内容 69 print(soup.p.text) # $37 70 71 # 5、嵌套选择 72 print(soup.html.head) 73 74 # 6、子节点、子孙节点 75 print(soup.body.children) # body所有子节点,返回的是迭代器对象 76 print(list(soup.body.children)) # 强转成列表类型 77 78 print(soup.body.descendants) # 子孙节点 79 print(list(soup.body.descendants)) # 子孙节点 80 81 # 7、父节点、祖先节点 82 print(soup.p.parent) # 获取p标签的父亲节点 83 # 返回的是生成器对象 84 print(soup.p.parents) # 获取p标签所有的祖先节点 85 print(list(soup.p.parents)) 86 87 # 8、兄弟节点 88 # 找下一个兄弟 89 print(soup.p.next_sibling) 90 # 找下面所有的兄弟,返回的是生成器 91 print(soup.p.next_siblings) 92 print(list(soup.p.next_siblings)) 93 94 # 找上一个兄弟 95 print(soup.a.previous_sibling) # 找到第一个a标签的上一个兄弟节点 96 # 找到a标签上面的所有兄弟节点 97 print(soup.a.previous_siblings) # 返回的是生成器 98 print(list(soup.a.previous_siblings)) 99 100 101 102 '''''' 103 html_doc = """<html><head><title>The Dormouse's story</title></head><body><p class="sister"><b>$37</b></p><p class="story" id="p">Once upon a time there were three little sisters; and their names were<b>tank</b><a href="http://example.com/elsie" class="sister" >Elsie</a>,<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;and they lived at the bottom of a well.<hr></hr></p><p class="story">...</p>""" 104 ''' 105 搜索文档树: 106 find() 找一个 107 find_all() 找多个 108 109 标签查找与属性查找: 110 标签: 111 name 属性匹配 112 attrs 属性查找匹配 113 text 文本匹配 114 115 - 字符串过滤器 116 字符串全局匹配 117 118 - 正则过滤器 119 re模块匹配 120 121 - 列表过滤器 122 列表内的数据匹配 123 124 - bool过滤器 125 True匹配 126 127 - 方法过滤器 128 用于一些要的属性以及不需要的属性查找。 129 130 属性: 131 - class_ 132 - id 133 ''' 134 135 from bs4 import BeautifulSoup 136 soup = BeautifulSoup(html_doc, 'lxml') 137 138 # # 字符串过滤器 139 # # name 140 # p_tag = soup.find(name='p') 141 # print(p_tag) # 根据文本p查找某个标签 142 # # 找到所有标签名为p的节点 143 # tag_s1 = soup.find_all(name='p') 144 # print(tag_s1) 145 # 146 # 147 # # attrs 148 # # 查找第一个class为sister的节点 149 # p = soup.find(attrs={"class": "sister"}) 150 # print(p) 151 # # 查找所有class为sister的节点 152 # tag_s2 = soup.find_all(attrs={"class": "sister"}) 153 # print(tag_s2) 154 # 155 # 156 # # text 157 # text = soup.find(text="$37") 158 # print(text) 159 # 160 # 161 # # 配合使用: 162 # # 找到一个id为link2、文本为Lacie的a标签 163 # a_tag = soup.find(name="a", attrs={"id": "link2"}, text="Lacie") 164 # print(a_tag) 165 166 167 168 # # 正则过滤器 169 # import re 170 # # name 171 # p_tag = soup.find(name=re.compile('p')) 172 # print(p_tag) 173 174 # 列表过滤器 175 # import re 176 # # name 177 # tags = soup.find_all(name=['p', 'a', re.compile('html')]) 178 # print(tags) 179 180 # - bool过滤器 181 # True匹配 182 # 找到有id的p标签 183 # p = soup.find(name='p', attrs={"id": True}) 184 # print(p) 185 186 # 方法过滤器 187 # 匹配标签名为a、属性有id没有class的标签 188 # def have_id_class(tag): 189 # if tag.name == 'a' and tag.has_attr('id') and tag.has_attr('class'): 190 # return tag 191 # 192 # tag = soup.find(name=have_id_class) 193 # print(tag) 194 195 196 197 ''' 198 主页: 199 图标地址、下载次数、大小、详情页地址 200 201 详情页: 202 游戏名、图标名、好评率、评论数、小编点评、简介、网友评论、1-5张截图链接地址、下载地址 203 https://www.wandoujia.com/wdjweb/api/category/more?catId=6001&subCatId=0&page=1&ctoken=FRsWKgWBqMBZLdxLaK4iem9B 204 205 https://www.wandoujia.com/wdjweb/api/category/more?catId=6001&subCatId=0&page=2&ctoken=FRsWKgWBqMBZLdxLaK4iem9B 206 207 https://www.wandoujia.com/wdjweb/api/category/more?catId=6001&subCatId=0&page=3&ctoken=FRsWKgWBqMBZLdxLaK4iem9B 208 209 32 210 ''' 211 import requests 212 from bs4 import BeautifulSoup 213 # 1、发送请求 214 def get_page(url): 215 response = requests.get(url) 216 return response 217 218 # 2、开始解析 219 # 解析主页 220 def parse_index(data): 221 soup = BeautifulSoup(data, 'lxml') 222 223 # 获取所有app的li标签 224 app_list = soup.find_all(name='li', attrs={"class": "card"}) 225 for app in app_list: 226 # print('tank *' * 1000) 227 # print(app) 228 # 图标地址 229 img = app.find(name='img').attrs['data-original'] 230 print(img) 231 232 # 下载次数 233 down_num = app.find(name='span', attrs={"class": "install-count"}).text 234 print(down_num) 235 236 import re 237 # 大小 238 size = soup.find(name='span', text=re.compile("\d+MB")).text 239 print(size) 240 241 # 详情页地址 242 detail_url = soup.find(name='a', attrs={"class": "detail-check-btn"}).attrs['href'] 243 print(detail_url) 244 245 246 def main(): 247 for line in range(1, 33): 248 url = f"https://www.wandoujia.com/wdjweb/api/category/more?catId=6001&subCatId=0&page={line}&ctoken=FRsWKgWBqMBZLdxLaK4iem9B" 249 250 # 1、往app接口发送请求 251 response = get_page(url) 252 # print(response.text) 253 print('*' * 1000) 254 # 反序列化为字典 255 data = response.json() 256 # 获取接口中app标签数据 257 app_li = data['data']['content'] 258 # print(app_li) 259 # 2、解析app标签数据 260 parse_index(app_li) 261 262 263 if __name__ == '__main__': 264 main() 265 266 267 268 ''' 269 主页: 270 图标地址、下载次数、大小、详情页地址 271 272 详情页: 273 游戏名、好评率、评论数、小编点评、下载地址、简介、网友评论、1-5张截图链接地址、 274 https://www.wandoujia.com/wdjweb/api/category/more?catId=6001&subCatId=0&page=1&ctoken=FRsWKgWBqMBZLdxLaK4iem9B 275 276 https://www.wandoujia.com/wdjweb/api/category/more?catId=6001&subCatId=0&page=2&ctoken=FRsWKgWBqMBZLdxLaK4iem9B 277 278 https://www.wandoujia.com/wdjweb/api/category/more?catId=6001&subCatId=0&page=3&ctoken=FRsWKgWBqMBZLdxLaK4iem9B 279 280 32 281 ''' 282 import requests 283 from bs4 import BeautifulSoup 284 # 1、发送请求 285 def get_page(url): 286 response = requests.get(url) 287 return response 288 289 # 2、开始解析 290 # 解析详情页 291 def parse_detail(text): 292 soup = BeautifulSoup(text, 'lxml') 293 # print(soup) 294 295 # app名称 296 name = soup.find(name="span", attrs={"class": "title"}).text 297 # print(name) 298 299 # 好评率 300 love = soup.find(name='span', attrs={"class": "love"}).text 301 # print(love) 302 303 # 评论数 304 commit_num = soup.find(name='a', attrs={"class": "comment-open"}).text 305 # print(commit_num) 306 307 # 小编点评 308 commit_content = soup.find(name='div', attrs={"class": "con"}).text 309 # print(commit_content) 310 311 # app下载链接 312 download_url = soup.find(name='a', attrs={"class": "normal-dl-btn"}).attrs['href'] 313 # print(download_url) 314 315 print( 316 f''' 317 ============= tank ============== 318 app名称:{name} 319 好评率: {love} 320 评论数: {commit_num} 321 小编点评: {commit_content} 322 app下载链接: {download_url} 323 ============= end ============== 324 ''' 325 ) 326 327 328 329 # 解析主页 330 def parse_index(data): 331 soup = BeautifulSoup(data, 'lxml') 332 333 # 获取所有app的li标签 334 app_list = soup.find_all(name='li', attrs={"class": "card"}) 335 for app in app_list: 336 # print(app) 337 # print('tank' * 1000) 338 # print('tank *' * 1000) 339 # print(app) 340 # 图标地址 341 # 获取第一个img标签中的data-original属性 342 img = app.find(name='img').attrs['data-original'] 343 print(img) 344 345 # 下载次数 346 # 获取class为install-count的span标签中的文本 347 down_num = app.find(name='span', attrs={"class": "install-count"}).text 348 print(down_num) 349 350 import re 351 # 大小 352 # 根据文本正则获取到文本中包含 数字 + MB(\d+代表数字)的span标签中的文本 353 size = soup.find(name='span', text=re.compile("\d+MB")).text 354 print(size) 355 356 # 详情页地址 357 # 获取class为detail-check-btn的a标签中的href属性 358 # detail_url = soup.find(name='a', attrs={"class": "name"}).attrs['href'] 359 # print(detail_url) 360 361 # 详情页地址 362 detail_url = app.find(name='a').attrs['href'] 363 print(detail_url) 364 365 # 3、往app详情页发送请求 366 response = get_page(detail_url) 367 368 # 4、解析app详情页 369 parse_detail(response.text) 370 371 372 def main(): 373 for line in range(1, 33): 374 url = f"https://www.wandoujia.com/wdjweb/api/category/more?catId=6001&subCatId=0&page={line}&ctoken=FRsWKgWBqMBZLdxLaK4iem9B" 375 376 # 1、往app接口发送请求 377 response = get_page(url) 378 # print(response.text) 379 print('*' * 1000) 380 # 反序列化为字典 381 data = response.json() 382 383 # 获取接口中app标签数据 384 app_li = data['data']['content'] 385 # print(app_li) 386 # 2、解析app标签数据 387 parse_index(app_li) 388 389 390 if __name__ == '__main__': 391 main() 392 393View Code
1 from pymongo import MongoClient 2 3 # 1、链接mongoDB客户端 4 # 参数1: mongoDB的ip地址 5 # 参数2: mongoDB的端口号 默认:27017 6 client = MongoClient('localhost', 27017) 7 # print(client) 8 9 # 2、进入tank_db库,没有则创建 10 # print(client['tank_db']) 11 12 # 3、创建集合 13 # print(client['tank_db']['people']) 14 15 # 4、给tank_db库插入数据 16 17 # 1.插入一条 18 # data1 = { 19 # 'name': 'lee', 20 # 'age': 18, 21 # 'sex': 'male' 22 # } 23 # client['tank_db']['people'].insert(data1) 24 25 # 2.插入多条 26 # data1 = { 27 # 'name': 'lee', 28 # 'age': 8, 29 # 'sex': 'male' 30 # } 31 # data2 = { 32 # 'name': '汪汪汪???', 33 # 'age':0, 34 # 'sex': 'female' 35 # } 36 # data3 = { 37 # 'name': '喵喵喵???', 38 # 'age': 9, 39 # 'sex': 'male' 40 # } 41 # client['tank_db']['people'].insert([data1, data2, data3]) 42 # 43 # # 5、查数据 44 # # 查看所有数据 45 # data_s = client['tank_db']['people'].find() 46 # print(data_s) # <pymongo.cursor.Cursor object at 0x000002EEA6720128> 47 # # 需要循环打印所有数据 48 # for data in data_s: 49 # print(data) 50 # 51 # # 查看一条数据 52 # data = client['tank_db']['people'].find_one() 53 # print(data) 54 55 # 官方推荐使用 56 # 插入一条insert_one 57 # client['tank_db']['people'].insert_one() 58 # 插入多条insert_many 59 # client['tank_db']['people'].insert_many()View Code