网页抓取数据百度百科(Python爬取《权力的游戏第八季》演员数据并分析数据爬取)

优采云 发布时间: 2021-12-05 18:07

  网页抓取数据百度百科(Python爬取《权力的游戏第八季》演员数据并分析数据爬取)

  Python爬取分析《权力的游戏第8季》演员数据

  数据爬取一、 浏览需要爬取的网页

  首先浏览要爬取的网页,也就是百度百科的“权力的游戏第八季”页面,发现演员表里有每个演员条目的链接。在这里你可以通过爬取获取每个演员的入口链接,方便你。爬取了每个actor的详细信息:

  

  然后进入龙母的入口页面:

  

  在这里找到它的基本信息:

  

  因此,我们可以将之前爬取得到的各个actor的入口链接进行爬取,然后爬取并保存各个actor的基本信息,方便后续的数据分析。

  二、 在百度百科中爬取《权力的游戏》第八季的演员阵容,获取各个演员的链接并存入文件

  import re

import requests

import json

import pandas

import os

import sys

from bs4 import BeautifulSoup

#获取请求

def getHTMLText(url,kv):

try:

r = requests.get(url, headers=kv)

r.raise_for_status()

r.encoding = r.apparent_encoding

return r.text

except Exception as e:

print(e)

#解析出演员姓名与链接数据并存入文件

def parserData(text):

soup = BeautifulSoup(text,'lxml')

review_list = soup.find_all('li',{'class':'pages'})

soup1 = BeautifulSoup(str(review_list),'lxml')

all_dts = soup1.find_all('dt')

stars = []

for dt in all_dts:

star = {}

star["name"] = dt.find('a').text

star["link"] = 'https://baike.baidu.com' + dt.find('a').get('href')

stars.append(star)

json_data = json.loads(str(stars).replace("\'","\""))

with open('work/'+'stars.json','w',encoding='UTF-8') as f:

json.dump(json_data,f,ensure_ascii=False)

  三、 爬取演员的详细信息并保存在文件中(每个演员的图片也下载保存)

  #爬取并解析出演员详细信息与图片并存入文件

def crawl_everyone(kv):

with open('work/' + 'stars.json', 'r', encoding='UTF-8') as file:

json_array = json.loads(file.read())

star_infos = []

for star in json_array:

star_info = {}

name = star['name']

link = star['link']

star_info['name'] = name

#向选手个人百度百科发送一个http get请求

r = requests.get(link,headers=kv)

soup = BeautifulSoup(r.text,'lxml')

#获取选手的国籍、星座、身高、出生日期等信息

base_info_div = soup.find('div',{'class':'basic-info cmn-clearfix'})

dls = base_info_div.find_all('dl')

for dl in dls:

dts = dl.find_all('dt')

for dt in dts:

if "".join(str(dt.text).split()) == '国籍':

star_info['nation'] =''.join(str(dt.find_next('dd').text).split()).replace("\n","").replace("[1]","")

if "".join(str(dt.text).split()) == '星座':

con_str=str(dt.find_next('dd').text).replace("\n","")

if '座' in con_str:

star_info['constellation'] = con_str[0:con_str.rfind('座')]

if "".join(str(dt.text).split()) == '身高':

if name=='约翰·C·布莱德利':

star_info['height'] ='173'

else:

height_str = str(dt.find_next('dd').text)

star_info['height'] =''.join(str(height_str[0:height_str.rfind('cm')]).split()).replace("\n","").replace("[2]","") .replace("[4]","")

if "".join(str(dt.text).split()) == '出生日期':

birth_day_str = str(dt.find_next('dd').text).replace("\n","")

if '年' in birth_day_str:

star_info['birth_day'] = birth_day_str[0:birth_day_str.rfind('年')]

star_infos.append(star_info)

#从个人百度百科页面中解析得到一个链接,该链接指向选手图片列表页面

if soup.select('.summary-pic a'):

pic_list_url = soup.select('.summary-pic a')[0].get('href')

pic_list_url = 'https://baike.baidu.com' + pic_list_url

#向选手图片列表页面发送http get请求

pic_list_response = requests.get(pic_list_url,headers=kv)

#对选手图片列表页面进行解析,获取所有图片链接

soup1 = BeautifulSoup(pic_list_response.text,'lxml')

pic_list_html=soup1.select('.pic-list img ')

pic_urls = []

for pic_html in pic_list_html:

pic_url = pic_html.get('src')

pic_urls.append(pic_url)

#根据图片链接列表pic_urls, 下载所有图片,保存在以name命名的文件夹中

down_save_pic(name,pic_urls)

#将个人信息存储到json文件中

#print("%s",name)

json_data = json.loads(str(star_infos).replace("\'","\""))

with open('work/' + 'stars_info.json', 'w', encoding='UTF-8') as f:

json.dump(json_data, f, ensure_ascii=False)

print('所有信息与图片爬取完成')

def down_save_pic(name,pic_urls):

#根据图片链接列表pic_urls, 下载所有图片,保存在以name命名的文件夹中,

path = 'work/'+'pics/'+name+'/'

if not os.path.exists(path):

os.makedirs(path)

for i, pic_url in enumerate(pic_urls):

try:

pic = requests.get(pic_url, timeout=15)

string = str(i + 1) + '.jpg'

with open(path+string, 'wb') as f:

f.write(pic.content)

#print('成功下载第%s张图片: %s' % (str(i + 1), str(pic_url)))

except Exception as e:

print('下载第%s张图片时失败: %s' % (str(i + 1), str(pic_url)))

print(e)

continue

# 调用函数爬取信息

kv={ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/67.0.3396.99 Safari/537.36' }

url = 'https://baike.baidu.com/item/%E6%9D%83%E5%8A%9B%E7%9A%84%E6%B8%B8%E6%88%8F%E7%AC%AC%E5%85%AB%E5%AD%A3'

html = getHTMLText(url,kv)

parserData(html)

crawl_everyone(kv)

  四、 爬取结果:

  1.保存的演员链接文件:

  

  2.保存的演员信息文件:

  

  3.下载保存的演员图片:

  

  数据分析一、生成演员年龄分布直方图

  import numpy as np

import json

import pandas as pd

import matplotlib.font_manager as font_manager

#显示matplotlib生成的图形

%matplotlib inline

df=pd.read_json('work/stars_info.json',dtype={'birth_day' : str})

grouped=df['name'].groupby(df['birth_day'])

s=grouped.count()

zone_list=s.index

count_list=s.values

#设置显示中文

plt.rcParams['font.sans-serif']=['SimHei']#指定默认字体

plt.figure(figsize=(20,15))

plt.bar(range(len(count_list)),count_list,color='r',tick_label=zone_list,facecolor='#FFC0CB',edgecolor='white')

#调节横坐标的倾斜度,rotation是读书,以及设置刻度字体大小

plt.xticks(rotation=45,fontsize=20)

plt.yticks(fontsize=20)

plt.legend()

plt.title('''《权力的游戏第八季》演员年龄分布图''',fontsize=24)

plt.savefig('work/result/birth_result.jpg')

plt.show()

  二、 生成演员国籍分布饼图

  import matplotlib.pyplot as plt

import numpy as np

import json

import matplotlib.font_manager as font_manager

with open('work/stars_info.json', 'r', encoding='UTF-8') as file:

json_array = json.loads(file.read())

#设置显示中文

plt.rcParams['font.sans-serif']=['SimHei']#指定默认字体

#绘制选手身高分布饼状图

nations = []

counts = []

for star in json_array:

if 'nation' in dict(star).keys():

nation = star['nation']

nations.append(nation)

print(nations)

nation_list = []

count_list = []

n1 = 0

n2 = 0

n3 = 0

n4 = 0

for nation in nations:

if nation == '英国':

n1 += 1

elif nation == '美国':

n2 += 1

elif nation == '丹麦':

n3 += 1

else:

n4 += 1

labels = '英国', '美国', '丹麦', '其它'

nas = [n1, n2, n3, n4]

explode = (0.2, 0.1, 0, 0)

fig1, ax1 = plt.subplots()

ax1.pie(nas, explode=explode, labels=labels, autopct='%1.1f%%',

shadow=True)

ax1.axis('equal')

plt.savefig('work/result/nation_result.jpg')

plt.title('''《权力的游戏第八季》演员国籍分布图''',fontsize = 14)

plt.show()

  三、生成演员身高分布饼图

<p>import matplotlib.pyplot as plt

import numpy as np

import json

import matplotlib.font_manager as font_manager

with open(&#39;work/stars_info.json&#39;, &#39;r&#39;, encoding=&#39;UTF-8&#39;) as file:

json_array = json.loads(file.read())

#设置显示中文

plt.rcParams[&#39;font.sans-serif&#39;]=[&#39;SimHei&#39;]#指定默认字体

#绘制选手身高分布饼状图

heights = []

counts = []

for star in json_array:

if &#39;height&#39; in dict(star).keys():

height = float(star[&#39;height&#39;][0:3])

heights.append(height)

print(heights)

size_list = []

count_list = []

size1 = 0

size2 = 0

size3 = 0

size4 = 0

for height in heights:

if height

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线