python爬虫 猫眼电影和电影天堂数据csv和mysql存储过程解析
字符串常用方法
#去掉左右空格
'helloworld'.strip()#'helloworld'
#按指定字符切割
'helloworld'.split('')#['hello','world']
#替换指定字符串
'helloworld'.replace('','#')#'hello#world'
csv模块
作用:将爬取的数据存放到本地的csv文件中
使用流程
- 导入模块
- 打开csv文件
- 初始化写入对象
- 写入数据(参数为列表)
importcsv
withopen('test.csv','w')asf:
writer=csv.writer(f)#初始化写入对象
#写一行
writer.writerow(['超哥哥',20])
writer.writerow(['步惊云',22])
withopen('test.csv','a')asf:
writer=csv.writer(f)
#写多行
data_list=[('聂风',23),('秦霜',30)]
writer.writerows(data_list)
Windows中使用csv模块默认会在每行后面添加一个空行,使用newline=''可解决
withopen('xxx.csv','w',newline='')asf:
猫眼电影top100抓取案例
确定URL网址
猫眼电影-榜单-top100榜目标
电影名称、主演、上映时间操作步骤
1、查看是否为动态加载
右键-查看网页源代码-搜索爬取关键字(查看在源代码中是否存在)
2、找URL规律
- 第1页:https://maoyan.com/board/4?offset=0
- 第2页:https://maoyan.com/board/4?offset=10
- 第n页:offset=(n-1)*10
3、正则表达式
4、编写程序框架,完善程序
- 打印程序执行时间
- 随机的User-Agent,(确保每次发请求使用随机)
- 数据爬下来后做处理(字符串),定义成字典
- 一条龙:获取->调用解析->数据处理
- 猫眼电影数据存入本地maoyanfilm.csv文件
fromurllibimportrequest
importtime
importre
importcsv
importrandom
classMaoyanSpider(object):
def__init__(self):
self.page=1#用于记录页数
self.url='https://maoyan.com/board/4?offset={}'
self.agent=[
'Mozilla/5.0(WindowsNT6.1;WOW64)AppleWebKit/535.1(KHTML,likeGecko)Chrome/14.0.835.163\
Safari/535.1',
'Mozilla/5.0(WindowsNT6.1;WOW64;rv:6.0)Gecko/20100101Firefox/6.0',
'Mozilla/4.0(compatible;MSIE8.0;WindowsNT6.1;WOW64;Trident/4.0;SLCC2;.NETCLR2.0.50727;\
.NETCLR3.5.30729;.NETCLR3.0.30729;MediaCenterPC6.0;.NET4.0C;InfoPath.3)',
'Mozilla/5.0(WindowsNT6.1;WOW64)AppleWebKit/535.1(KHTML,likeGecko)Chrome/14.0.835.163Safari/535.1']
#请求
defget_page(self,url):
headers={'User-Agent':random.choice(self.agent)}#每次使用随机的user-agent
req=request.Request(url=url,headers=headers)#创建请求对象
res=request.urlopen(req)#发起请求
html=res.read().decode('utf-8')#获取请求内容
self.parse_page(html)#直接调用解析函数
#解析
defparse_page(self,html):
pattren=re.compile(
'.*?title="(.*?)".*?class="star">(.*?).*?releasetime">(.*?)',re.S)
r_list=pattren.findall(html)
#rlist:[('霸王别姬','\n主演:张国荣,张丰毅,巩俐\n','上映时间:1993-01-01'),(...),(...)]
self.write_page(r_list)#写入csv文件
##保存,打印输出
#defwrite_page(self,r_list):
#one_film_dict={}
#forrtinr_list:
#one_film_dict['name']=rt[0].strip()
#one_film_dict['star']=rt[1].strip()
#one_film_dict['time']=rt[2].strip()[5:15]
#
#print(one_film_dict)
#保存到csv文件(writerows)--推荐使用此方法
defwrite_page(self,r_list):
#空列表,最终writerows()的参数:[(),(),()]
film_list=[]
withopen('maoyan.csv','a',newline="")asf:
writer=csv.writer(f)
forrtinr_list:
#把处理过的数据定义成元组
t=(rt[0],rt[1].strip(),rt[2].strip()[5:15])
film_list.append(t)
writer.writerows(film_list)
defmain(self):
foroffsetinrange(0,31,10):
url=self.url.format(offset)
self.get_page(url)
time.sleep(random.randint(1,3))
print('第%d页爬取完成'%self.page)
self.page+=1
if__name__=='__main__':
start=time.time()
spider=MaoyanSpider()
spider.main()
end=time.time()
print('执行时间:%.2f'%(end-start))
数据持久化存储(MySQL数据库)
让我们来回顾一下pymysql模块的基本使用
importpymysql
db=pymysql.connect('localhost','root','123456','maoyandb',charset='utf8')
cursor=db.cursor()#创建游标对象
#execute()方法第二个参数为列表传参补位
cursor.execute('insertintofilmvalues(%s,%s,%s)',['霸王别姬','张国荣','1993'])
db.commit()#提交到数据库执行
cursor.close()#关闭
db.close()
让我们来回顾一下pymysql中executemany()的用法
importpymysql
#数据库连接对象
db=pymysql.connect('localhost','root','123456',charset='utf8')
cursor=db.cursor()#游标对象
ins_list=[]#存放所有数据的大列表
foriinrange(2):
name=input('请输入第%d个学生姓名:'%(i+1))
age=input('请输入第%d个学生年龄:'%(i+1))
ins_list.append([name,age])
ins='insertintot3values(%s,%s)'#定义插入语句
cursor.executemany(ins,ins_list)#一次数据库的IO操作可插入多条语句,提升性能
db.commit()#提交到数据库执行
cursor.close()#关闭游标
db.close()#关闭数据库
ins='insertintomaoyanfilmvalues(%s,%s,%s)'
cursor.execute(['霸王','国荣','1991'])
cursor.executemany([
['月光宝盒','周星驰','1993'],
['大圣娶亲','周星驰','1993']])
练习:把猫眼电影案例中电影信息存入MySQL数据库中(尽量使用executemany方法)
fromurllibimportrequest
importtime
importre
importpymysql
importrandom
classMaoyanSpider(object):
def__init__(self):
self.page=1#用于记录页数
self.url='https://maoyan.com/board/4?offset={}'
self.ua_list=[
'Mozilla/5.0(WindowsNT6.1;WOW64)AppleWebKit/535.1(KHTML,likeGecko)\
Chrome/14.0.835.163Safari/535.1',
'Mozilla/5.0(WindowsNT6.1;WOW64;rv:6.0)Gecko/20100101Firefox/6.0',
'Mozilla/4.0(compatible;MSIE8.0;WindowsNT6.1;WOW64;Trident/4.0;SLCC2;\
.NETCLR2.0.50727;.NETCLR3.5.30729;.NETCLR3.0.30729;MediaCenterPC6.0;.NET4.0C;InfoPath.3)']
#创建数据库连接对象和游标对象
self.db=pymysql.connect('localhost','root','123456','maoyandb',charset='utf8')
self.cursor=self.db.cursor()
#获取
defget_page(self,url):
#每次使用随机的user-agent
headers={'User-Agent':random.choice(self.ua_list)}
req=request.Request(url=url,headers=headers)
res=request.urlopen(req)
html=res.read().decode('utf-8')
self.parse_page(html)#直接调用解析函数
#解析
defparse_page(self,html):
pattren=re.compile(
'.*?title="(.*?)".*?class="star">(.*?).*?releasetime">(.*?)',re.S)
#rlist:[('霸王别姬','张国荣','1993'),(),()]
r_list=pattren.findall(html)
print(r_list)
self.write_page(r_list)
#存入mysql数据库(executemany([[],[],[]]))
defwrite_page(self,r_list):
film_list=[]
ins='insertintofilmtabvalues(%s,%s,%s)'#定义插入语句
#处理数据,放到大列表film_list中
forrtinr_list:
one_film=[rt[0],rt[1].strip(),rt[2].strip()[5:15]]
#添加到大列表中
film_list.append(one_film)
#一次数据库IO把1页数据存入
self.cursor.executemany(ins,film_list)
#提交到数据库执行
self.db.commit()
defmain(self):
foroffsetinrange(0,31,10):
url=self.url.format(offset)
self.get_page(url)
time.sleep(random.randint(1,3))
print('第%d页爬取完成'%self.page)
self.page+=1
#断开数据库(所有页爬完之后)
self.cursor.close()
self.db.close()
if__name__=='__main__':
start=time.time()
spider=MaoyanSpider()
spider.main()
end=time.time()
print('执行时间:%.2f'%(end-start))
让我们来做个SQL命令查询
1、查询20年以前的电影的名字和上映时间
selectname,timefromfilmtabwheretime<(now()-interval20year);
2、查询1990-2000年的电影名字和上映时间
selectname,timefromfilmtabwheretime>='1990-01-01'andtime<='2000-12-31';
让我们来复习一下mongdb数据库
importpymongo
#1.连接对象
conn=pymongo.MongoClient(host='127.0.0.1',port=27017)
db=conn['maoyandb']#2.库对象
myset=db['filmtab']#3.集合对象
myset.insert_one({'name':'赵敏'})#4.插入数据库
练习:把猫眼电影案例中电影信息存入MongDB数据库中
fromurllibimportrequest
importre
importtime
importrandom
importpymongo
classMaoyanSpider(object):
def__init__(self):
self.url='https://maoyan.com/board/4?offset={}'
#计数
self.num=0
#创建3个对象
self.conn=pymongo.MongoClient('localhost',27017)
self.db=self.conn['maoyandb']
self.myset=self.db['filmset']
self.ua_list=[
'Mozilla/5.0(WindowsNT6.1;WOW64)AppleWebKit/535.1(KHTML,likeGecko)Chrome/14.0.835.163Safari/535.1',
'Mozilla/5.0(WindowsNT6.1;WOW64;rv:6.0)Gecko/20100101Firefox/6.0',
'Mozilla/4.0(compatible;MSIE8.0;WindowsNT6.1;WOW64;Trident/4.0;SLCC2;.NETCLR2.0.50727;.NET\
CLR3.5.30729;.NETCLR3.0.30729;MediaCenterPC6.0;.NET4.0C;InfoPath.3)',]
defget_html(self,url):
headers={
'User-Agent':random.choice(self.ua_list)
}
req=request.Request(url=url,headers=headers)
res=request.urlopen(req)
html=res.read().decode('utf-8')
#直接调用解析函数
self.parse_html(html)
defparse_html(self,html):
re_bds=r'.*?title="(.*?)".*?class="star">(.*?).*?releasetime">(.*?)'
pattern=re.compile(re_bds,re.S)
#film_list:[('霸王别姬','张国荣','1993'),()]
film_list=pattern.findall(html)
#直接调用写入函数
self.write_html(film_list)
#mongodb数据库
defwrite_html(self,film_list):
forfilminfilm_list:
film_dict={
'name':film[0].strip(),
'star':film[1].strip(),
'time':film[2].strip()[5:15]
}
#插入mongodb数据库
self.myset.insert_one(film_dict)
defmain(self):
foroffsetinrange(0,31,10):
url=self.url.format(offset)
self.get_html(url)
time.sleep(random.randint(1,2))
if__name__=='__main__':
start=time.time()
spider=MaoyanSpider()
spider.main()
end=time.time()
print('执行时间:%.2f'%(end-start))
电影天堂案例(二级页面抓取)
1、查看是否为静态页面,是否为动态加载
右键-查看网页源代码
2、确定URL地址
百度搜索:电影天堂-2019年新片-更多
3、目标
*********一级页面***********
1、电影名称
2、电影链接
*********二级页面***********
1、下载链接
4、步骤
找URL规律
第1页:https://www.dytt8.net/html/gndy/dyzz/list_23_1.html
第2页:https://www.dytt8.net/html/gndy/dyzz/list_23_2.html
第n页:https://www.dytt8.net/html/gndy/dyzz/list_23_n.html
写正则表达式
1、一级页面正则表达式(电影名称、电影详情链接)
2、二级页面正则表达式
代码实现
#decode('gbk','ignore')注意ignore参数
#注意结构和代码可读性(一个函数不要太冗余)
fromurllibimportrequest
importre
importtime
importrandom
fromuseragentsimport*
importpymysql
classFilmSky(object):
def__init__(self):
self.url='https://www.dytt8.net/html/gndy/dyzz/list_23_{}.html'
#定义两个对象
self.db=pymysql.connect('127.0.0.1','root','123456','maoyandb',charset='utf8')
self.cursor=self.db.cursor()
#获取html函数(因为两个页面都需要发请求)
defget_page(self,url):
req=request.Request(url=url,headers={'User-Agent':random.choice(ua_list)})
res=request.urlopen(req)
#ignore参数,实在处理不了的编码错误忽略
#查看网页源码,发现网页编码为gb2312,不是utf-8
html=res.read().decode('gbk','ignore')
returnhtml
#解析提取数据(把名称和下载链接一次性拿到)
#html为一级页面响应内容
defparse_page(self,html):
#1.先解析一级页面(电影名称和详情链接)
pattern=re.compile('.*?(.*?)',re.S)
#film_list:[('详情链接','名称'),()]
film_list=pattern.findall(html)
#[('/html/gndy/dyzz/20190806/58956.html','019年惊悚动作《报仇雪恨/血债血偿》BD中英双字幕'),(),()]
ins='insertintofilmskyvalues(%s,%s)'
forfilminfilm_list:
film_name=film[1]
film_link='https://www.dytt8.net'+film[0]
#2.拿到详情链接后,再去获取详情链接html,提取下载链接
download_link=self.parse_two_html(film_link)
self.cursor.execute(ins,[film_name,film_link])
self.db.commit()
#打印测试
d={'电影名称':film_name,'下载链接':download_link}
print(d)
#{'电影名称':'019年惊悚动作《报仇雪恨/血债血偿》BD中英双字幕','下载链接':'ftp://ygdy8:ygdy8@yg90.dydytt.net:8590/阳光电影www.ygdy8.com.报仇雪恨.BD.720p.中英双字幕.mkv'}
#解析二级页面,获取下载链接
defparse_two_html(self,film_link):
two_html=self.get_page(film_link)
pattern=re.compile('.*?>(.*?)',re.S)
download_link=pattern.findall(two_html)[0]
returndownload_link
#主函数
defmain(self):
forpageinrange(1,11):
url=self.url.format(page)
html=self.get_page(url)
self.parse_page(html)
time.sleep(random.randint(1,3))
print('第%d页完成'%page)
if__name__=='__main__':
start=time.time()
spider=FilmSky()
spider.main()
end=time.time()
print('执行时间:%.2f'%(end-start))
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。