python--- bs4和requests模組
阿新 • • 發佈:2018-11-08
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')