老版:Python 爬取内容存入Excel实例
这是之前用python2.7
写的,最近看博友评论,因网页结构调整和python3
的普及,代码运行后报错、得不到数据。于是,使用python3重写了一次,顺便做下改进。
网页解析可以去看下之前的文章,这里不作赘述。
环境:python 3.6.5
所需包安装:pip install requests bs4 lxml openpyxl
先上代码,后分析
'''
function:爬取豆瓣top250的电影信息,并写入Excel文件
env:python3.6.5
author:jxc
'''
import time
import requests
import re
from openpyxl import workbook # 写入Excel表所用
from bs4 import BeautifulSoup as bs
class Top250:
def __init__(self):
#起始地址
self.start_url = 'https://movie.douban.com/top250'
#请求头,浏览器模拟
self.headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36',
}
#爬取页数
self.page_num = 10
'''url拼接'''
def get_page_url(self):
n = 0 #第一页开始,下标0
while n<self.page_num:
yield self.start_url+'?start={}&filter='.format(n*25)
n += 1
'''获取页面源码'''
def getHtml(self):
gu = self.get_page_url() #url生成器
for url in gu:
html = requests.get(url,headers=self.headers).text
yield html
'''电影数据提取'''
def getData(self):
gh = self.getHtml() # html源码生成器
for html in gh: # html:网页源码
soup = bs(html, 'lxml')
for info in soup.find_all('div', class_='info'):
c_name = info.find('span',class_='title').text.strip() # 得到电影中文名
message = info.select('div.bd p')[0].text.strip() #得到导演、主演、年份、地区信息
yat = re.search('[0-9]+.*\/?', message).group().split('/') #得到年份、地区、类型信息列表
year,area,type = yat[0],yat[1],yat[2]#得到年份、地区、类型
da = re.search('导演.+\s',message).group().strip()+'...' #得到导演、主演混合信息
director = re.findall('导演:(.+?)\s',da)[0].strip() #得到导演信息
#得到主演信息,不存在时发生异常,进行异常处理
try:
mainActors = re.findall('主演:(.+?)[.,]+',da)[0].strip()
except IndexError:
mainActors = '暂无主演信息'
mark_info = info.find('div',class_='star') #得到评分、评价人数混合信息
score= mark_info.find('span',class_='rating_num').text.strip()#得到评分
count = re.search('[0-9]+',mark_info.select('span')[3].text).group() #得到评价人数
#得到简介,捕捉不存在时的异常
try:
quote = info.select('p.quote span')[0].text.strip()
except IndexError:
quote = '该影片暂时无简介'
yield [c_name,year,area,type,director,mainActors,score,count,quote]
'''保存到excel文件
:param file_name:文件名
'''
def saveToExcel(self,file_name):
wb = workbook.Workbook() # 创建Excel对象
ws = wb.active # 获取当前正在操作的表对象
ws.append(['电影名', '年份', '地区', '剧情类型', '导演', '主演', '评分', '评论人数', '简介'])
gd = self.getData() #数据生成器
for data in gd:
ws.append(data)
wb.save(file_name)
if __name__ == '__main__':
start = time.time()
top = Top250()
try:
top.saveToExcel('top250.xlsx')
print('抓取成功,用时%4.2f'%(time.time()-start)+'秒')
except Exception as e:
print('抓取失败,原因:%s'%e)
re
进行匹配抓取,不熟悉的可以先去看下正则表达式-菜鸟教程re.findall()
方法,在前后加上不变的条件,变化的部分使用()
包裹,这样就能直接得到想要的信息,不用再次切片获取。如代码中的re.findall('导演:(.+?)\s',da)[0]
,就能直接得到导演信息。try...except
捕获异常yield生成器
,实现抓取流水线操作欢迎留言讨论~
【不想研究代码的,博主将结果上传到了csdn,资源直达——>top250.xlsx】
博主其他文章推荐:
[1] 【python实用特性】- 迭代、可迭代对象、迭代器
[2] 【python实用特性】- 列表生成式
[3] 【python实用特性】- yield生成器
[4] 【python实用特性】- 装饰器
[5] 【Matplotlib】-自定义坐标轴刻度完成20万+数据的可视化
[6] Python+selenium实现自动爬取实例
[7] requests 设置请求头、代理
[8] requests使用cookie模拟登陆豆瓣
[9] requests使用session保持会话