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></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></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) #
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></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="")
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
393
View 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