• Python-爬取豆瓣电影信息并存到mysql


    一、基本流程

    继续之前的博客,进行最后的完工:https://www.cnblogs.com/hhjing/p/13419881.html

    二、程序源码

    import urllib.request,urllib.error  #指定URL获取网页数据
    import bs4  #网页解析数据获取
    import re   #正则表达式,进行文字匹配的
    import xlwt  #进行excel操作
    import sqlite3  #进行SQLite数据库操作
    import pymysql  #进行mysql数据库操作
    from bs4 import  BeautifulSoup
    
    #主函数
    def main():
        baseurl="https://movie.douban.com/top250?start="
        #1.爬取网页    #2.逐一解析数据
        dataList=getDate(baseurl)
       # dbpath="database.db"
        #3.连接数据库,并保存数据
        saveData(dataList);
        #askURL("https://movie.douban.com/top250?start=")
    
    #影片详情链接的规则
    findLink=re.compile(r'<a href="(.*?)">')   #生成正则表达式对象,表示规则(字符串的模式)
    #影片图片的规则
    findImgSrc=re.compile(r'<img.*src="(.*?)"',re.S)    #re.S让换行符包含在字符中,然后进行比对
    #影片片名的规则
    findTitle=re.compile(r'<span class="title">(.*)</span>')
    #影片评分的规则
    findRating=re.compile(r'<span class="rating_num" property="v:average">(.*)</span>')
    #找到评价人数
    findJudge=re.compile(r'<span>(d*)人评价</span>')
    #找到概况
    findInq=re.compile(r'<span class="inq">(.*)</span>')
    #找到影片的相关内容
    findBd=re.compile(r'<p class="">(.*?)</p>',re.S)
    
    
    
    #-------------------------相关函数-----------------------------
    #1.爬取网页
    def getDate(baseurl):
        dataList=[]
        for i in range(0,10):  #循环爬取页面,调用活页页面信息的函数10次
            url=baseurl+str(i*25)
            html= askURL(url)  #保存获取到的网页源码
    
            #2.逐一解析数据
            soup=BeautifulSoup(html,"html.parser")  #"html.parser"是一种页面解析器
            for item in soup.find_all('div',class_="item"): #查找符合要求的字符串,找到能够完整提出一个影片内容的项,即页面中所有样式是item类的div
                #print(item)    #测试:查看电影item全部信息
                data=[] #保存一部电影的所有信息
                item=str(item)
    
                #获取影片详情链接
                link=re.findall(findLink,item)[0]   #re库用来通过正则表达式查找指定的字符串
                data.append(link)   #添加链接
    
                imgSrc=re.findall(findImgSrc,item)[0]
                data.append(imgSrc)     #添加图片
    
                titles=re.findall(findTitle,item)   #片名可能只有一个中文名
                if(len(titles)==2):  #片名可能有两个国家的名
                    ctitle=titles[0]
                    data.append(ctitle)     #添加中国名
                    etitle=titles[1].replace("/","")    #去掉无关的"/"符号
                    data.append(etitle)     #添加外国名
                else:
                    data.append(titles[0])
                    data.append(' ')    #外国名留空,为使后面的信息保存到数据库或者表格中不篡位
    
                rating=re.findall(findRating,item)[0]
                data.append(rating)     #添加评分
    
                judgeNum=re.findall(findJudge,item)[0]
                data.append(judgeNum)      #添加评价人数
    
                inq=re.findall(findInq,item)
                if len(inq)!=0:
                    inq=inq[0].replace("","")      #替换句号
                    data.append(inq)
                else:
                    data.append(" ")    #留空,为使后面的信息保存到数据库或者表格中不篡位
    
                bd=re.findall(findBd,item)[0]
                bd=re.sub('<br(s+)?/>(s+)?'," ",bd)    #去掉<br/>
                bd=re.sub("/"," ",bd)   #替换/
                data.append(bd.strip())     #去掉前后的空格
    
                dataList.append(data)       #把处理好的一部电影信息放入到dataList
    
        return dataList
    
    
    
    #得到指定一个URL的网页内容
    def askURL(url):
        head={   #模拟浏览器头部消息,向豆瓣服务器发送消息
            "User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36"
        }
        #用户代理表示告诉豆瓣服务器,我们是什么类型的机器,浏览器(本质上是告诉浏览器,我们可以接收什么水平的文件内容)
        request=urllib.request.Request(url,headers=head)
        html=""
        try:
            response=urllib.request.urlopen(request)
            html=response.read().decode("utf-8")
            #print(html)
        except urllib.error.URLError as e:
            if hasattr(e,"code"):
                print(e.code)
            if hasattr(e,"reason"):
                print(e.reason)
        return html
    
    
    
    #3.连接数据库,并保存数据
    def saveData(dataList):
        db = pymysql.connect(host = 'localhost', port=3306, user='root', password='20000604', db='myself', charset='utf8')
        #使用cursor方法生成一个游标
        cursor=db.cursor()
    
        for data in dataList:
            for index in range(len(data)):
                data[index]='"'+data[index]+'"'
            sql='''
                    insert into movie250(info_link,pic_link,cname,ename,soore,rated,instrodction,info)
                    values(%s)'''%",".join(data)
            print(sql)
            cursor.execute(sql)
            db.commit()
        cursor.close()
        db.close()
    
    
    if __name__=="__main__":   #当程序执行时,更容易管理代码主流程(程序入口)
    #调用函数
        main();
    spider

    三、运行截图

    四、遇到的问题

    1.在爬取解析数据的时候,出现信息串位的问题

      原因:有的电影有中英文,还有的篇名没有相关的评价,需要留空

       

    2.开始时数据存入到mysql的时候,保存失败

      测试方法:先使用print(sql)输出相关语句,查找问题以及出错原因

      出错原因:sql语句位置写错了,写在了for循环里边,python是根据错位来判断执行顺序的,所以需要更加注意代码编写的规范

  • 相关阅读:
    关于BigDecimal转String的准确性问题
    MyBatis动态Sql之if标签的注意事项
    Servlet与通信协议概述
    关于ThreadLocal的那些事
    MyBatis 中 @Param 注解的四种使用场景
    Mybatis中#{}与${}的区别
    如何重新加载 Spring Boot 上的更改,而无需重新启动服务器?
    jsp有哪些动作?作用分别是什么?
    forward 和redirect的区别 ?
    Eureka和ZooKeeper都可以提供服务注册与发现的功能,请说说两个的区别?
  • 原文地址:https://www.cnblogs.com/hhjing/p/13455804.html
Copyright © 2020-2023  润新知