Python爬⾍——爬取⾖瓣top250完整代码
说在前头:
本次仅仅只是记录使⽤Python⽹络爬⾍爬取⾖瓣top250排⾏榜榜单的内容,爬取其它⽹页同理,可能爬取难度不同,但步骤类似。
注意:建议把 html ⽂件先爬取到本地保存,再从本地读取 html 进⾏后⾯的数据解析和保存操作,因为频繁访问同⼀个页⾯,可能被⽹站判定为异常访问⽽拒绝该IP访问资源,连切换为真实浏览器访问都可能会受限。
准备⼯作:
  本次使⽤⾖瓣top250⽹址:
主要步骤:
爬取⽹页
服务器返回给我们的是⼀个html⽂件,然后浏览器解析服务器返回的⽂件,通过解析呈现出我们平时看到的精彩⽹页内容,我们这⼀步骤要拿的,就是这个服务器返回发给我们的东西
⾸页的⽹址是:movie.douban/top250 或 movie.douban/top250?start=
点击第⼆页的⽹址是:movie.douban/top250?start=25&filter=
同理第三页的⽹址是:movie.douban/top250?start=50&filter=
不⽤管filter过滤器,可以发现规律,第page页的 start=25*(page-1)
baseurl = 'movie.douban/top250?start='  ,然后通过循环让字符串拼接 url = baseurl + str(i)
i = 0, 25, 50, 75 ...... 就可以获取 top250 其它页的内容
借助 quest 获取 html,伪装成真实浏览器的报头,不然⾖瓣会返回 418错误(我是茶壶)
获取html后保存在本地,最好保存在本地,避免每次都访问,因为频繁访问top250有可能被⾖瓣标记为异常访问
解析数据
解析保存的html⽂件,内容都在html⽂件中,我们要想办法把所需内容所在的标签块出来,并根据规则到所需的内容所在位置,把内容提取出来结束beautifulSoup解析标签块,再结合re正则表达式提取所需的内容
将获取的内容存⼊列表或者类对象中
保存数据
前⾯已经解析数据并保存在了列表或者对象之中,变量释放空间就没了,我们要做的是把东西保存在本地的⽂件中
保存获取的内容到本地text,执⾏⽂本读取操作
或者excel,借助xlwt包写⼊excel,借助xlrd包读取excel
完整代码:
# -*- coding = utf-8 -*-
# 解析⽹页
from bs4 import BeautifulSoup as bf
# 正则表达式
import re
# Excel表格操作
import xlwt
# 获取URL得到html⽂件
quest as req
# 设置单独全局变量,如需更加规范,也可以将电影信息封装成⼀个class类⽐如 class Movie: ...
# 电影名称
find_name = repile(r'<span class="title">(.*?)</span>')
# 电影播放地址链接
find_link = repile(r'<a href="(.*?)">')
# 电影封⾯的地址链接,re.S让换⾏符包含在字符中
find_imgSrc = repile(r'<img.*src="(.*?)"', re.S)
# 电影评分
find_score = repile(r'<span class="rating_num".*>(.*?)</span>')
# 评分⼈数
find_num = repile(r'<span>(\d*⼈)评价</span>')
# 名句
find_inq = repile(r'<span class="inq">(.*?)</span>')
# 有些电影没有某些项,所以查长度为0的时候,设置该项为空
def set_film(file, content):
# 检查查内容的长度,如果不为0,说明查到内容,则将内容转换成字符串类型
if len(re.findall(file, content)) != 0:
film = str(re.findall(file, content)[0])
else:
film = ""
return film
# 保存获取的html,避免出现ip异常的情况
def write_html(path, html):
file = open(path, 'w', encoding='utf-8')
file.write(str(html))
file.close()
# 循环获取所有的html页⾯并提取所需信息保存到 data_list 列表
def get_data():
# 获得多有页⾯有价值的信息,然后集中存放与data_list列表中
data_list = []
# 循环遍历,修改?start=起始排⾏序号,获取不同分页的⾖瓣top信息,url分页格式去⾖瓣换页内容试试# 例如第⼀页第 top 0-24,第⼆页是top 25-49条 ?start=25 这个参数,会让服务器响应第⼆页的25条信息for i in range(0, 250, 25):
# 使⽤⼆进制读取,这点很重要,报错⽆数次
html = open('Data/html/html' + str(i//25) + '.html', 'rb')
# 接下来是逐⼀解析数据
bs = bf(html, 'html.parser')
# 使⽤标签 + 属性组合查,查<div class="item"></div>的标签块
# 注意:class是关键字,所以这⾥需要使⽤ class_ 代替
f_list = bs.find_all('div', class_="item")
# 使⽤re.findall(x, s) 或者 x.findall(s)效果⼀样
for f in f_list:
data = []
# 将正则表达式提取的内容赋值给⾃定义变量
file_name = set_film(find_name, str(f))
file_num = set_film(find_num, str(f))
file_link = set_film(find_link, str(f))
file_img_src = set_film(find_imgSrc, str(f))
file_score = set_film(find_score, str(f))
file_inq = set_film(find_inq, str(f))
# 将所有需要的数据保存到data列表
data.append(file_name)
data.append(file_score)
data.append(file_num)
data.append(file_link)
data.append(file_img_src)
data.append(file_inq)
# 写⼊data(单条电影信息)列表,到总的 data_list(所有电影信息)列表
data_list.append(data)
html.close()
return data_list
# 保存⾖瓣的各页html⽂件
def save_douban_html(base_url):
for i in range(0, 250, 25):
# 使⽤基础地址 'movie.douban/top250?start='  +  偏移地址如 '25'
url = base_url + str(i)
# 获取html保存在本地,⽅便之后爬⾍操作,因为频繁爬取可能被⾖瓣发现异常
html = ask_url(url)
# 将⽂件批量保存在 Data/html/ ⽬录下 i//25 是整除,命名格式如  html0.html  html1.html ...
write_html('Data/html/html' + str(i//25) + '.html', html)
# 获取html信息,并返回html信息
def ask_url(url):
# 设置传给服务器的header头部信息,伪装⾃⼰是正规浏览器访问
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.81 Safari/537.36 SE 2.X MetaSr 1.0"    }
# ⽤于保存获取的html⽂件
html = ""
# 最好⽤ try-except 捕捉异常
try:
# 封装⼀个Request对象,将⾃定义的头部信息加⼊进去
res = req.Request(url, headers=headers)
# 向指定的url获取响应信息,设置超时,防⽌长时间耗在⼀个页⾯
response = req.urlopen(res, timeout=10)
# 读取html信息,使⽤decode('utf-8')解码
html = ad().decode('utf-8')
# 如果出错,就捕捉报错信息并打印出,这⾥使⽤Exception 泛泛的意思⼀下
except Exception as error:
# 出现异常时候,打印报错信息
print("Ask_url is Error : " + error)
# 将获得的html页⾯信息返回
return html
# 以下split、main两个函数和 if __name__ 程序主⼊⼝是我个⼈编程习惯,与上述内容⽆本质关联
# 定义分隔线长度,并返回分割线字符串
def split(num):
str1 = ""
for i in range(1, num):
# print("------------", end='')
str1 += "------------"
return str1
# 读取⽂件⽂本
def read_file(file_name):
# 打开⽂本选择读模式
file = open(file_name, 'r', encoding='utf-8')
ad())
file.close()
# 保存数据到txt⽂本中
def save_data_txt(datas, save_file):
# 打开⽂本选择写模式,并指定编码格式
file = open(save_file, 'w', encoding='utf-8')
# 不能直接写⼊list,所以通过遍历⼀条条写⼊
for data in datas:
for dat in data:python index函数
file.write(dat + '\n')
file.write(split(10) + '\n')
file.close()
# 设置excel的单元格字体样式
def set_font(bold, size, horz):
# 创建xlwt格式对象
style_font = xlwt.XFStyle()
# 设置字体是否为粗体
style_font.font.bold = bold
# 设置字体尺⼨⼤⼩
style_font.font.height = size
# 字体是否居中
if horz:
# 设置字体⽔平居中
style_font.alignment.horz = 0x02
# 设置字体垂直居中
style_font.alignment.vert = 0x01
# 设置单元格⾃动换⾏
style_font.alignment.wrap = False
# 返回设置的字体样式
return style_font
# 保存数据到excel⽂件中
def save_data_excel(datas, save_path):
# 创建⼀个xlwt对象,使⽤utf-8编码格式
excel = xlwt.Workbook(encoding='utf-8')
# 创建⼀个⼯作表,命名为top250
sheet = excel.add_sheet('top250')
# 设置前六列的列宽
width_c = [256*20, 256*6, 256*12, 256*42, 256*72, 256*68]
for i in range(0, 6):
# 设置三种单元格样式 set_font(粗体,尺⼨,居中)
style_font_title = set_font(True, 240, True)
style_font_content = set_font(False, 220, True)
style_font_content1 = set_font(False, 220, False)
# 表格各列的列名
titles = ['电影名称', '评分', '评论数', '电影链接', '图⽚链接', '电影名⾔']
index = 0
# 将标题写⼊excel
for title in titles:
# (单元格⾏序号,单元格列序号,单元格的内容,单元格样式)
sheet.write(0, index, title, style_font_title)
index += 1
# 将数据写⼊excel
index_r = 1
# 从多条电影中每次取出⼀条
for data in datas:
index_c = 0
# 从⼀条电影中每次取出⼀个属性
for item in data:
# 前三列设置居中对齐
if index_c <= 2:
sheet.write(index_r, index_c, item, style_font_content)
# 后三列设置默认对齐,即左对齐
else:
sheet.write(index_r, index_c, item, style_font_content1)
index_c += 1
index_r += 1
# 保存excel⽂件到指定路径
excel.save(save_path)
# 主程序
def main():
base_url = "movie.douban/top250?start="
# 1.爬取⽹页
# 从⾖瓣上获取html⽂件并保存到本地⽬录下,该⽅法成功执⾏⼀次即可,保存html,接下来本地操作# save_douban_html(base_url)
# 2.解析数据
# 逐个解析保存在本地的html⽂件
datas = get_data()
# 3.保存数据
# 保存爬取数据到本地txt⽂件
# save_txt_path = 'Data/'
# save_data_txt(datas, save_txt_path)
# 将读取的txt⽂本打印到控制台
# read_file('Data/')
# 保存爬取数据到本地excel⽂件
save_excel_path = 'Data/excel/top250.xls'
save_data_excel(datas, save_excel_path)
# 打印⾃定义分界线
print(split(10))
# 主程序⼊⼝
if __name__ == '__main__':
main()
存储为⽂本⽂件 ——
存储为excel⽂件 —— top250.xls

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。