1. 程式人生 > >python--- bs4和requests模組

python--- bs4和requests模組

1.bs4模組

bs4庫 是解析、遍歷、維護、“標籤樹“的功能庫。通俗一點說就是: bs4庫把html原始碼重新進行了格式化,從而方便我們對其中的節點、標籤、屬性等進行操作。

  • 獲取標籤內容
from bs4 import  BeautifulSoup

# 構造物件
soup = BeautifulSoup(open('westos.html'), 'html.parser')
# 獲取標籤, 預設獲取找到的第一個符合的內容
print(soup.title)
print(type(soup.title))
print(soup.p)

在這裡插入圖片描述

  • 獲取標籤屬性
print(soup.p.attrs)
# 獲取標籤指定屬性的內容
print(soup.p['id'])
print(soup.p['class'])
print(soup.p['style'])

# 對屬性進行修改
soup.p['id'] = 'modifyid'
print(soup.p)
print(type(soup.p))
  • 獲取標籤的文字內容
from bs4 import  BeautifulSoup

# 構造物件
soup = BeautifulSoup(open('westos.html'), 'html.parser')
print(dir(soup.title))
print(soup.title.text)
print(soup.title.string)
print(soup.title.name)
print(soup.head.title.string)
  • 操作子節點
# 構造物件
soup = BeautifulSoup(open('westos.html'), 'html.parser')
print(soup.head.contents)
print(soup.head.children)
for el in soup.head.children:
    print('--->', el)
  • 面向物件的匹配
# # 查詢指定的標籤內容(指定的標籤)
# res1 = soup.find_all('p')
# print(res1)
# # 查詢指定的標籤內容(指定的標籤)--與正則的使用
res1 = soup.find_all(re.compile(r'd+'))
print(res1)

# # 對於正則表示式進行編譯, 提高查詢速率;
# pattern = r'd.+'
# pattern = re.compile(pattern)
# print(re.findall(pattern, 'dog hello d'))

import re
from bs4 import  BeautifulSoup

# 構造物件
soup = BeautifulSoup(open('westos.html'), 'html.parser')

# 詳細查詢標籤
print(soup.find_all('p', id='test1'))
print(soup.find_all('p', id=re.compile(r'test\d{1}')))
print(soup.find_all('p', class_="class1"))
print(soup.find_all('p', class_=re.compile(r'class\d{1}')))
# 查詢多個標籤
print(soup.find_all(['p', 'div']))
print(soup.find_all([re.compile('^d'), re.compile('p')]))


# 內容的匹配
print(soup.find_all(text='文章標題'))
print(soup.find_all(text=re.compile('標題')))
print(soup.find_all(text=[re.compile('標題'), 'Title']))
  • CSS匹配
import re
from bs4 import  BeautifulSoup
# 構造物件
soup = BeautifulSoup(open('westos.html'), 'html.parser')
# CSS常見選擇器: 標籤選擇器(div), 類選擇器(.class1), id選擇器(#idname), 屬性選擇器(p[type="text"])
# 標籤選擇器(div)
res1 = soup.select("p")
print(res1)
# 類選擇器(.class1)
res2 = soup.select(".class2")
print(res2)
# id選擇器(#idname)
res3 = soup.select("#test1")
print(res3)
#  屬性選擇器(p[type="text"]
print(soup.select("p[id='test1']"))
print(soup.select("p['class']"))

2.獲取豆瓣最新電影的id號和電影名稱

import  requests
from bs4 import BeautifulSoup

url = "https://movie.douban.com/cinema/nowplaying/xian/"
# 1). 獲取頁面資訊
response = requests.get(url)
content = response.text
# print(content)
# 2). 分析頁面, 獲取id和電影名
soup = BeautifulSoup(content, 'lxml')
# 線找到所有的電影資訊對應的li標籤;
nowplaying_movie_list = soup.find_all('li', class_='list-item')
# print(nowplaying_movie_list[0])
# print(type(nowplaying_movie_list[0]))
# 儲存所有電影資訊[{'title':"名稱", "id":"id號"}]
movies_info = []

# 依次遍歷每一個li標籤, 再次提取需要的資訊
for item in nowplaying_movie_list:
    nowplaying_movie_dict = {}
    # 根據屬性獲取title內容和id內容
    # item['data-title']獲取li標籤裡面的指定屬性data-title對應的value值;
    nowplaying_movie_dict['title'] = item['data-title']
    nowplaying_movie_dict['id'] = item['id']
    nowplaying_movie_dict['actors'] = item['data-actors']
    nowplaying_movie_dict['director'] = item['data-director']

    # 將獲取的{'title':"名稱", "id":"id號"}新增到列表中;
    movies_info.append(nowplaying_movie_dict)

print(movies_info)

在這裡插入圖片描述

4.獲取指定電影的影評資訊

# 目標:
#      1). 爬取某一頁的評論資訊;
#      2).爬取某個電影的前10頁評論資訊;
#      3). 獲取所有電影的評論資訊;
import threading

import requests
from bs4 import  BeautifulSoup
# #      1). 爬取某一頁的評論資訊;
def getOnePageComment(id, pageNum):
    # 1). 根據頁數確定start變數的值
    # 第一頁: https://movie.douban.com/subject/26425063/comments?start=0&limit=20&sort=new_score&status=P
    # 第二頁: https://movie.douban.com/subject/26425063/comments?start=20&limit=20&sort=new_score&status=P
    # 第三頁: https://movie.douban.com/subject/26425063/comments?start=20&limit=40&sort=new_score&status=P
    start = (pageNum-1)*20
    url = "https://movie.douban.com/subject/%s/comments?start=%s&limit=20&sort=new_score&status=P" %(id, start)
    # 2). 爬取評論資訊的網頁內容
    content = requests.get(url).text
    # 3). 通過bs4分析網頁
    soup = BeautifulSoup(content, 'lxml')
    # 分析網頁得知, 所有的評論資訊都是在span標籤, 並且class為short;
    commentsList = soup.find_all('span', class_='short')
    pageComments = ""
    # 依次遍歷每一個span標籤, 獲取標籤裡面的評論資訊, 並將所有的評論資訊儲存到pageComments變數中;
    for commentTag in commentsList:
        pageComments += commentTag.text
    # return pageComments
    print("%s page" %(pageNum))
    global  comments
    comments += pageComments

#      2).爬取某個電影的前10頁評論資訊;
id = '26425063'
comments = ''
threads = []
# 爬取前10頁的評論資訊;獲取前幾頁就迴圈幾次;
for pageNum in range(10): # 0 , 1 2 3 4...9
    pageNum = pageNum + 1
    # getOnePageComment(id, pageNum)
    # 通過啟動多執行緒獲取每頁評論資訊
    t = threading.Thread(target=getOnePageComment, args=(id, pageNum))
    threads.append(t)
    t.start()
#     等待所有的子執行緒執行結束, 再執行主執行緒內容;
_ = [thread.join() for thread in threads]
print("執行結束")
with open("%s.txt" %(id), 'w') as f:
    f.write(comments)

在這裡插入圖片描述

5.資料清洗

import re
import wordcloud
import jieba

# 1. 對於爬取的評論資訊進行資料清洗(刪除不必要的逗號, 句號, 表情, 只留下中文或者英文內容)
with open('./doc/26425063.txt') as f:
    comments = f.read()
# 通過正則表示式實現
pattern = re.compile(r'([\u4e00-\u9fa5]+|[a-zA-Z]+)')
deal_comments = re.findall(pattern, comments)
newComments = ''
for item in deal_comments:
    newComments += item
print(newComments)

6.詞雲分析

import jieba
import  wordcloud
import  numpy as np
from PIL import Image

text= "馬雲曾公開表態稱對錢沒興趣稱其從來沒碰過錢上了微博熱搜"

# 2).  '微博熱', '搜'切割有問題, 可以強調
# jieba.suggest_freq(('微博'),True)
# jieba.suggest_freq(('熱搜'),True)
# 強調檔案中出現的所有詞語;
jieba.load_userdict('./doc/newWord')
# 1). 切割中文, lcut返回一個列表, cut返回一個生成器;
result = jieba.lcut(text)
print("切分結果:", result)

# 4). 繪製詞雲
wc = wordcloud.WordCloud(
    background_color='snow',
    font_path='./font/msyh.ttf',    # 處理中文資料時
    min_font_size=5,    # 圖片中最小字型大小;
    max_font_size=15,   # 圖片中最大字型大小;
    width=200,  # 指定生成圖片的寬度
)
wc.generate(",".join(result))
wc.to_file('./doc/douban.png')

7.電影評論詞雲分析

import jieba
import  wordcloud
import  numpy as np
# 在python2中處理影象,Image; python3中如果處理影象, 千萬不要安裝Image, 安裝pillow
from PIL import Image

# 1). 切割中文, lcut返回一個列表, cut返回一個生成器;
result = jieba.lcut(open('./doc/26425063.txt').read())

# 2). 開啟圖片
imageObj = Image.open('./doc/mao.jpg')
cloud_mask = np.array(imageObj)

# 4). 繪製詞雲
wc = wordcloud.WordCloud(
    mask = cloud_mask,
    background_color='black',
    font_path='./font/msyh.ttf',    # 處理中文資料時
    min_font_size=5,    # 圖片中最小字型大小;
    max_font_size=50,   # 圖片中最大字型大小;
    width=500,  # 指定生成圖片的寬度
)
wc.generate(",".join(result))
wc.to_file('./doc/douban.png')