Day0八、BeautifulSoup解析庫,MongoDB存儲庫,requests-html請求庫

1、解析庫之bs4html

'''
pip3 install beautifulsoup4  # 安裝bs4
pip3 install lxml  # 下載lxml解析器
'''
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
<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.</p>

<p class="story">...</p>
"""

# 從bs4中導入BeautifulSoup
from bs4 import BeautifulSoup

# 調用BeautifulSoup實例化獲得一個soup對象
# 參數一: 解析文本
# 參數二:
# 參數二: 解析器(html.parser、lxml...)
soup = BeautifulSoup(html_doc, 'lxml')

print(soup)
print('*' * 100)
print(type(soup))
print('*' * 100)
# 文檔美化
html = soup.prettify()
print(html)

  

2、bs4之遍歷文檔樹python

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>"""

from bs4 import BeautifulSoup
soup = BeautifulSoup(html_doc, 'lxml')

'''
遍歷文檔樹:
    一、直接使用
    二、獲取標籤的名稱
    三、獲取標籤的屬性
    四、獲取標籤的內容
    五、嵌套選擇
    六、子節點、子孫節點
    七、父節點、祖先節點
    八、兄弟節點
'''

# 一、直接使用
print(soup.p)  # 查找第一個p標籤
print(soup.a)  # 查找第一個a標籤

# 二、獲取標籤的名稱
print(soup.head.name)  # 獲取head標籤的名稱

# 三、獲取標籤的屬性
print(soup.a.attrs)  # 獲取a標籤中的全部屬性
print(soup.a.attrs['href'])  # 獲取a標籤中的href屬性

# 四、獲取標籤的內容
print(soup.p.text)  # $37

# 五、嵌套選擇
print(soup.html.head)

# 六、子節點、子孫節點
print(soup.body.children)  # body全部子節點,返回的是迭代器對象
print(list(soup.body.children))  # 強轉成列表類型

print(soup.body.descendants)  # 子孫節點
print(list(soup.body.descendants))  # 子孫節點

#  七、父節點、祖先節點
print(soup.p.parent)  # 獲取p標籤的父親節點
# 返回的是生成器對象
print(soup.p.parents)  # 獲取p標籤全部的祖先節點
print(list(soup.p.parents))

# 八、兄弟節點
# 找下一個兄弟
print(soup.p.next_sibling)
# 找下面全部的兄弟,返回的是生成器
print(soup.p.next_siblings)
print(list(soup.p.next_siblings))

# 找上一個兄弟
print(soup.a.previous_sibling)  # 找到第一個a標籤的上一個兄弟節點
# 找到a標籤上面的全部兄弟節點
print(soup.a.previous_siblings)  # 返回的是生成器
print(list(soup.a.previous_siblings))

  

3、bs4之搜索文檔樹web

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>"""
'''
搜索文檔樹:
    find()  找一個  
    find_all()  找多個
    
標籤查找與屬性查找:
    標籤:
            name 屬性匹配
            attrs 屬性查找匹配
            text 文本匹配
            
        - 字符串過濾器   
            字符串全局匹配

        - 正則過濾器
            re模塊匹配

        - 列表過濾器
            列表內的數據匹配

        - bool過濾器
            True匹配

        - 方法過濾器
            用於一些要的屬性以及不須要的屬性查找。

    屬性:
        - class_
        - id
'''

from bs4 import BeautifulSoup
soup = BeautifulSoup(html_doc, 'lxml')

# # 字符串過濾器
# # name
# p_tag = soup.find(name='p')
# print(p_tag)  # 根據文本p查找某個標籤
# # 找到全部標籤名爲p的節點
# tag_s1 = soup.find_all(name='p')
# print(tag_s1)
#
#
# # attrs
# # 查找第一個class爲sister的節點
# p = soup.find(attrs={"class": "sister"})
# print(p)
# # 查找全部class爲sister的節點
# tag_s2 = soup.find_all(attrs={"class": "sister"})
# print(tag_s2)
#
#
# # text
# text = soup.find(text="$37")
# print(text)
#
#
# # 配合使用:
# # 找到一個id爲link二、文本爲Lacie的a標籤
# a_tag = soup.find(name="a", attrs={"id": "link2"}, text="Lacie")
# print(a_tag)



# # 正則過濾器
# import re
# # name
# p_tag = soup.find(name=re.compile('p'))
# print(p_tag)

# 列表過濾器
# import re
# # name
# tags = soup.find_all(name=['p', 'a', re.compile('html')])
# print(tags)

# - bool過濾器
# True匹配
# 找到有id的p標籤
# p = soup.find(name='p', attrs={"id": True})
# print(p)

# 方法過濾器
# 匹配標籤名爲a、屬性有id沒有class的標籤
# def have_id_class(tag):
#     if tag.name == 'a' and tag.has_attr('id') and tag.has_attr('class'):
#         return tag
#
# tag = soup.find(name=have_id_class)
# print(tag)

  

4、爬取豌豆莢app數據(提取遊戲主頁)mongodb

'''
主頁:
    圖標地址、下載次數、大小、詳情頁地址

詳情頁:
    遊戲名、圖標名、好評率、評論數、小編點評、簡介、網友評論、1-5張截圖連接地址、下載地址
https://www.wandoujia.com/wdjweb/api/category/more?catId=6001&subCatId=0&page=1&ctoken=FRsWKgWBqMBZLdxLaK4iem9B

https://www.wandoujia.com/wdjweb/api/category/more?catId=6001&subCatId=0&page=2&ctoken=FRsWKgWBqMBZLdxLaK4iem9B

https://www.wandoujia.com/wdjweb/api/category/more?catId=6001&subCatId=0&page=3&ctoken=FRsWKgWBqMBZLdxLaK4iem9B

32
'''
import requests
from bs4 import BeautifulSoup
# 一、發送請求
def get_page(url):
    response = requests.get(url)
    return response

# 二、開始解析
# 解析主頁
def parse_index(data):
    soup = BeautifulSoup(data, 'lxml')

    # 獲取全部app的li標籤
    app_list = soup.find_all(name='li', attrs={"class": "card"})
    for app in app_list:
        # print('tank *' * 1000)
        # print(app)
        # 圖標地址
        img = app.find(name='img').attrs['data-original']
        print(img)

        # 下載次數
        down_num = app.find(name='span', attrs={"class": "install-count"}).text
        print(down_num)

        import re
        # 大小
        size = soup.find(name='span', text=re.compile("\d+MB")).text
        print(size)

        # 詳情頁地址
        detail_url = soup.find(name='a', attrs={"class": "detail-check-btn"}).attrs['href']
        print(detail_url)


def main():
    for line in range(1, 33):
        url = f"https://www.wandoujia.com/wdjweb/api/category/more?catId=6001&subCatId=0&page={line}&ctoken=FRsWKgWBqMBZLdxLaK4iem9B"

        # 一、往app接口發送請求
        response = get_page(url)
        # print(response.text)
        print('*' * 1000)
        # 反序列化爲字典
        data = response.json()
        # 獲取接口中app標籤數據
        app_li = data['data']['content']
        # print(app_li)
        # 二、解析app標籤數據
        parse_index(app_li)


if __name__ == '__main__':
    main()

  

5、爬取豌豆莢app數據2數據庫

'''
主頁:
    圖標地址、下載次數、大小、詳情頁地址

詳情頁:
    遊戲名、好評率、評論數、小編點評、下載地址、簡介、網友評論、1-5張截圖連接地址、
https://www.wandoujia.com/wdjweb/api/category/more?catId=6001&subCatId=0&page=1&ctoken=FRsWKgWBqMBZLdxLaK4iem9B

https://www.wandoujia.com/wdjweb/api/category/more?catId=6001&subCatId=0&page=2&ctoken=FRsWKgWBqMBZLdxLaK4iem9B

https://www.wandoujia.com/wdjweb/api/category/more?catId=6001&subCatId=0&page=3&ctoken=FRsWKgWBqMBZLdxLaK4iem9B

32
'''
import requests
from bs4 import BeautifulSoup
# 一、發送請求
def get_page(url):
    response = requests.get(url)
    return response

# 二、開始解析
# 解析詳情頁
def parse_detail(text):
    soup = BeautifulSoup(text, 'lxml')
    # print(soup)

    # app名稱
    name = soup.find(name="span", attrs={"class": "title"}).text
    # print(name)

    # 好評率
    love = soup.find(name='span', attrs={"class": "love"}).text
    # print(love)

    # 評論數
    commit_num = soup.find(name='a', attrs={"class": "comment-open"}).text
    # print(commit_num)

    # 小編點評
    commit_content = soup.find(name='div', attrs={"class": "con"}).text
    # print(commit_content)

    # app下載連接
    download_url = soup.find(name='a', attrs={"class": "normal-dl-btn"}).attrs['href']
    # print(download_url)

    print(
        f'''
        ============= tank ==============
        app名稱:{name}
        好評率: {love}
        評論數: {commit_num}
        小編點評: {commit_content}
        app下載連接: {download_url}
        ============= end ==============
        '''
    )



# 解析主頁
def parse_index(data):
    soup = BeautifulSoup(data, 'lxml')

    # 獲取全部app的li標籤
    app_list = soup.find_all(name='li', attrs={"class": "card"})
    for app in app_list:
        # print(app)
        # print('tank' * 1000)
        # print('tank *' * 1000)
        # print(app)
        # 圖標地址
        # 獲取第一個img標籤中的data-original屬性
        img = app.find(name='img').attrs['data-original']
        print(img)

        # 下載次數
        # 獲取class爲install-count的span標籤中的文本
        down_num = app.find(name='span', attrs={"class": "install-count"}).text
        print(down_num)

        import re
        # 大小
        # 根據文本正則獲取到文本中包含 數字 + MB(\d+表明數字)的span標籤中的文本
        size = soup.find(name='span', text=re.compile("\d+MB")).text
        print(size)

        # 詳情頁地址
        # 獲取class爲detail-check-btn的a標籤中的href屬性
        # detail_url = soup.find(name='a', attrs={"class": "name"}).attrs['href']
        # print(detail_url)

        # 詳情頁地址
        detail_url = app.find(name='a').attrs['href']
        print(detail_url)

        # 三、往app詳情頁發送請求
        response = get_page(detail_url)

        # 四、解析app詳情頁
        parse_detail(response.text)


def main():
    for line in range(1, 33):
        url = f"https://www.wandoujia.com/wdjweb/api/category/more?catId=6001&subCatId=0&page={line}&ctoken=FRsWKgWBqMBZLdxLaK4iem9B"

        # 一、往app接口發送請求
        response = get_page(url)
        # print(response.text)
        print('*' * 1000)
        # 反序列化爲字典
        data = response.json()

        # 獲取接口中app標籤數據
        app_li = data['data']['content']
        # print(app_li)
        # 二、解析app標籤數據
        parse_index(app_li)


if __name__ == '__main__':
    main()

  

6、pymongo簡單使用json

from pymongo import MongoClient

# 一、連接mongoDB客戶端
# 參數1: mongoDB的ip地址
# 參數2: mongoDB的端口號 默認:27017
client = MongoClient('localhost', 27017)
# print(client)

# 二、進入tank_db庫,沒有則建立
# print(client['tank_db'])

# 三、建立集合
# print(client['tank_db']['people'])

# 四、給tank_db庫插入數據

# 1.插入一條
# data1 = {
#     'name': 'tank',
#     'age': 18,
#     'sex': 'male'
# }
# client['tank_db']['people'].insert(data1)

# 2.插入多條
# data1 = {
#     'name': 'tank',
#     'age': 18,
#     'sex': 'male'
# }
# data2 = {
#     'name': '戚志雲',
#     'age': 84,
#     'sex': 'female'
# }
# data3 = {
#     'name': '沈金金',
#     'age': 73,
#     'sex': 'male'
# }
# client['tank_db']['people'].insert([data1, data2, data3])
#
# # 五、查數據
# # 查看全部數據
# data_s = client['tank_db']['people'].find()
# print(data_s)  # <pymongo.cursor.Cursor object at 0x000002EEA6720128>
# # 須要循環打印全部數據
# for data in data_s:
#     print(data)
#
# # 查看一條數據
# data = client['tank_db']['people'].find_one()
# print(data)

# 官方推薦使用
# 插入一條insert_one
# client['tank_db']['people'].insert_one()
# 插入多條insert_many
# client['tank_db']['people'].insert_many()

  

課堂筆記api

一、BeautifulSoup 解析庫
二、MongoDB 存儲庫
三、requests-html 請求庫

BeautifulSoup
一、什麼bs4,爲何要使用bs4?
    是一個基於re開發的解析庫,能夠提供一些強大的解析功能。
    提升提取數據的效率與爬蟲開發效率。

二、安裝與使用
    pip3 install beautifulsoup4  # 安裝bs4
    pip3 install lxml  # 下載lxml解析器

MongoDB 非關係型數據庫
一 安裝與使用
一、下載安裝
    https://www.mongodb.com/download-center/community

二、在C盤建立一個data/db文件夾
    - 數據的存放路徑

三、mongod啓動服務
    進入終端,輸入mongod啓動mongoDB服務。

四、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
一、下載第三方模塊pymongo
    pip3 install pymongo

二、連接mongoDB客戶端
    client = MongoClient('localhost', 27017)

做業:
一、整理課堂內容,並寫博客

二、基於豌豆莢爬取剩下的簡介截圖圖片地址、網友評論

三、把豌豆莢爬取的數據插入mongoDB中
    - 建立一個wandoujia庫
        - 把主頁的數據存放一個名爲index集合中
        - 把詳情頁的數據存放一個名爲detail集合中
相關文章
相關標籤/搜索