neuqacm技术组周会-python爬虫实战

爬取豆瓣top250电影的所有信息并且存入表格和数据库

源码及注释:

# 爬取豆瓣top250电影的所有信息
import urllib.request, urllib.error  # 用于发送网络请求和requests功能相近
from bs4 import BeautifulSoup  # 用于解析网页
import re  # 用于正则匹配
import xlwt  # 用于表格的操作
import sqlite3  # 用于数据库的操作


def main():
    dbpath = "movie.db"  # 数据库路径(相对路径)
    base_url = "https://movie.douban.com/top250?start="  # 待爬取网页
    data_list = get_data(base_url)  # 获取数据
    save_xls(data_list)  # 存储数据进表格
    save_db(data_list, dbpath)  # 存储数据进数据库


def ask_url(url):  # 访问网页的函数
    head = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Firefox/86.0"
    }  # 用于绕过418反爬虫机制
    request = urllib.request.Request(url=url, headers=head)  # 制作请求头
    try:
        response = urllib.request.urlopen(request)  # 用于访问网页
        html = response.read().decode("utf-8")  # 接收网页信息
    except urllib.error.URLError as e:  # 异常处理
        if hasattr(e, "code"):
            print(e.code)  # 打印状态码
        if hasattr(e, "reason"):
            print(e.reason)  # 打印异常原因
    return html


def get_data(base_url):
    data_list = []  # 用于存取250条数据
    for i in range(10):
        url = base_url + str(i * 25)  # 制作目标网页列表
        html = ask_url(url)
        soup = BeautifulSoup(html, "html.parser")  # 解析网页,形成树型数据结构
        for item in soup.find_all("div", {"class": "item"}):  # 获取class=item的div内容
            data = []  # 用于存一部电影的所有信息
            item = str(item)
            link = re.findall(r'<a href="(.*?)">', item)[0]  # 获取详情链接
            data.append(link)
            img_src = re.findall(r'<img alt=.*? class="" src="(.*?)"', item)[0]  # 获取图片链接
            data.append(img_src)
            title = re.findall(r'<span class="title">(.*?)</span>', item)[0]  # 获取电影名
            data.append(title)
            other_title = re.findall(r'<span class="other">(.*?)</span>', item)[0]  # 获取其他名字
            if len(other_title) != 0:
                data.append(other_title.replace("\xa0/\xa0", " "))  # 替代掉不能识别的部分
            else:
                data.append(" ")  # 对于没有其他标题的电影用空格占位,防止存入表格和数据库的时候出现问题
            rating = re.findall(r'<span class="rating_num" property="v:average">(.*?)</span>', item)[0]  # 获取评分
            data.append(rating)
            rating_number = re.findall(r'span>(\d+)人评价</span>', item)[0]  # 获取评价人数
            data.append(rating_number)
            inq = re.findall(r'<span class="inq">(.*?)</span>', item)  # 获取评语
            if len(inq) != 0:
                inq = " ".join(inq)  # 从列表中取出数据
                data.append(inq.replace("。", " "))  # 用空格替代句号
            else:
                data.append("")  # 对于没有评价的电影用空格占位,防止存入表格和数据库的时候出现问题
            find_info = re.compile(r'<p class="">(.*?)</p>', re.S)
            info = re.findall(find_info, item)[0]
            info = info.replace("<br/>", " ")  # 替换多余部分
            info = info.replace("\n", " ")
            info = info.strip()  # 去除首尾空格
            data.append(info.replace("\xa0", " "))  # 替代掉不能识别的部分
            data_list.append(data)  # 存进总列表
    return data_list


def save_xls(data_list):
    book = xlwt.Workbook(encoding="utf-8")  # 建工作簿,用utf-8编码
    sheet = book.add_sheet("top250")  # 建工作表
    title = ["电影详情", "图片", "电影名", "其他名称", "评分", "评价人数", "评语", "其他信息"]  # 设置标题栏
    for i in range(8):
        sheet.write(0, i, title[i])  # 写入标题
    for i in range(250):
        data = data_list[i]  # 获取单条数据
        for j in range(8):
            sheet.write(i + 1, j, data[j])  # 存入数据
    book.save("test.xls")  # 数据库路径(相对路径)


def create_db(dbpath):  # 建表
    con = sqlite3.connect(dbpath)  # 建立数据库连接
    cur = con.cursor()  # 获取游标
    sql = '''
        create table movie250
        (
            id integer primary key autoincrement,
            link text,
            img_scr text,
            title varchar ,
            other_title varchar ,
            rating numeric ,
            rating_number numeric ,
            inq text,
            info text
        )
    '''
    cur.execute(sql)  # 执行sql语句
    cur.close()  # 关闭游标
    con.close()  # 关闭数据库


def save_db(data_list, dbpath):
    con = sqlite3.connect(dbpath)  # 建立数据库连接
    cur = con.cursor()  # 获取游标
    for data in data_list:
        for index in range(len(data)):  # 给每条数据加双引号,以符合数据库语言
            data[index] = '"' + data[index] + '"'
        sql = '''
            insert into movie250
            (
                link,img_scr,title,other_title,rating,rating_number,inq,info
            )
            values (%s)''' % ",".join(data)  # 从列表中取出数据
        cur.execute(sql)  # 执行sql语句
        con.commit()  # 提交操作
    cur.close()  # 关闭游标
    con.close()  # 关闭数据库


if __name__ == '__main__':  # 如果运行的是该文件则执行如下操作
    main()

  • 10
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 15
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Henrik-Yao

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值