Python---爬虫学习(详细注释/优化)

python 复制代码
from bs4 import BeautifulSoup
import re  # 正则表表达式文字匹配
import urllib.request, urllib.error  # 指定url,获取网页数据
import xlwt
findlink = re.compile(r'a href="(.*?)">')  # 电影链接
findImageSrc = 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)  # 相关信息

def main():
    # 定义基础URL,用于构造完整的URL来请求数据
    baseurl = "https://movie.douban.com/top250?start="
    # 调用getdata函数,传入基础URL,获取数据并返回
    datalist = getdata(baseurl)
    # 打印获取到的数据列表
    print(datalist)
    # 定义保存路径,将数据保存到movies.xls文件中
    savepath = ".\\movies.xls"  # 保存路径
    # 调用saveData函数,传入获取到的数据列表和保存路径,保存数据
    saveData(datalist, savepath)

# 定义函数,用于发送HTTP请求并获取返回的HTML内容
def askURL(url):
    # 定义字典,作为HTTP请求的头部信息
    head = {
        "User-Agent": " Mozilla / 5.0(Linux;Android6.0;Nexus5 Build / MRA58N) AppleWebKit / 537.36(KHTML, likeGecko) Chrome / 99.0.4844.51Mobile Safari / 537.36"
    }
    # 根据给定的URL和头部信息,构造一个HTTP请求对象
    request = urllib.request.Request(url, headers=head)
    # 初始化一个空字符串,用于存储HTML内容
    html = ""
    try:
        # 使用urllib.request的urlopen函数,发送HTTP请求并获取响应对象
        response = urllib.request.urlopen(request)
        # 从响应对象中读取HTML内容,并解码为utf-8格式的字符串
        html = response.read().decode('utf-8')
        # 注释:打印HTML内容(实际代码被注释掉)
        # print(html)
    except urllib.error.URLError as e:
        # 如果发生URL相关的错误,处理异常
        if hasattr(e, "code"):
            # 打印异常中的错误代码
            print(e.code)
        if hasattr(e, "reason"):
            # 打印异常中的错误原因描述
            print(e.reason)
    return html  # 返回获取到的HTML内容

# 爬取网页
def getdata(baseurl):
    # 初始化一个空的数据列表,用于存放解析出的数据
    datalist = []

    # 从基础URL开始,循环请求10次,每次请求偏移25
    for i in range(0, 10):
        url = baseurl + str(i * 25)  # 构造完整的URL
        html = askURL(url)  # 发送HTTP请求并获取HTML内容
        soup = BeautifulSoup(html, "html.parser")  # 使用BeautifulSoup解析HTML内容
        # 遍历解析出的每一个'div'标签,类名为"item"
        for item in soup.find_all('div', class_="item"):
            # 初始化一个空的数据列表,用于存放当前item的数据
            data = []
            item = str(item)  # 将item转换为字符串,以便进行正则表达式匹配
            # 寻找链接
            link = re.findall(findlink, item)[0]  # 使用正则表达式匹配链接
            data.append(link)  # 将链接添加到数据列表中
            # 寻找图片源地址
            image = re.findall(findImageSrc, item)[0]  # 使用正则表达式匹配图片源地址
            data.append(image)  # 将图片源地址添加到数据列表中
            # 寻找标题
            title = re.findall(findTitle, item)  # 使用正则表达式匹配标题
            if (len(title) == 2):  # 如果匹配到两个标题
                ctitle = title[0]  # 第一个标题
                data.append(ctitle)  # 将第一个标题添加到数据列表中
                otitle = title[1].replace("/", "")  # 第二个标题,移除其中的"/"字符
                data.append(otitle.strip())  # 将第二个标题添加到数据列表中,并移除首尾的空格
            else:  # 如果只匹配到一个标题
                data.append(title[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)  # 替换HTML中的换行标签为空格字符,这里可能需要考虑HTML转义字符的问题。
            # 并且这里只替换了一次,可能存在重复替换的问题。导演和主演的信息可能需要分别处理。
            bd = re.sub('/', " ", bd)  # 将"/"替换为空格字符,这里可能存在错误,因为"/ "在正则表达式中被错误地转义了
# 3 保存数据
# 定义saveData的函数,接收两个参数:datalist和savepath
def saveData(datalist, savepath):
    # 打印"save...",表示开始保存数据
    print("save...")
    # 创建一个Excel工作簿,设置编码为utf-8,样式压缩为0
    book = xlwt.Workbook(encoding="utf-8", style_compression=0)
    # 在工作簿中添加一个名为'movies'的工作表,设置cell_overwrite_ok为True,表示允许覆盖单元格内容
    sheet = book.add_sheet('movies', cell_overwrite_ok=True)
    # 定义一个包含列名的列表
    col = ("Movies_link", "Image_link", "Chinese_name", "Foreign_name", "Rating", "Reviews", "概况", "Summary")
    # 循环遍历col中的每一个元素,从0到7,将元素写入到工作表的第0行对应列中
    for i in range(0, 8):
        sheet.write(0, i, col[i])
        # 循环遍历datalist中的每一个元素,从0到249
    for i in range(0, 250):
        # 打印当前处理的条目序号
        print("第%d条" % (i + 1))

        # 从datalist中获取第i个元素,赋值给data
        data = datalist[i]

        # 循环遍历data中的每一个元素,从0到7,将元素写入到工作表的第i+1行对应列中
        for j in range(0, 8):
            sheet.write(i + 1, j, data[j])

            # 将工作簿保存到指定的路径下,文件名为savepath
    book.save(savepath)
    
main()
print("爬取完毕!")

项目结构:

  1. 导入库
  2. 正则表达式:用于匹配网页中电影信息中的链接、图片标题等
  3. 主程序:调用get_data和save_data
  4. HTTP请求函数:ask_URL
  5. 获取电影数据函数:get_data à 把信息保存data_list中
  6. 保存数据函数:save_data
相关推荐
云泽野4 小时前
【Java|集合类】list遍历的6种方式
java·python·list
IMPYLH6 小时前
Python 的内置函数 reversed
笔记·python
科技苑7 小时前
简单 Python 爬虫程序设计
爬虫
小赖同学啊8 小时前
物联网数据安全区块链服务
开发语言·python·区块链
码荼8 小时前
学习开发之hashmap
java·python·学习·哈希算法·个人开发·小白学开发·不花钱不花时间crud
武昌库里写JAVA9 小时前
Oracle如何使用序列 Oracle序列使用教程
java·开发语言·spring boot·学习·课程设计
小陈phd9 小时前
李宏毅机器学习笔记——梯度下降法
人工智能·python·机器学习
kk爱闹9 小时前
【挑战14天学完python和pytorch】- day01
android·pytorch·python
Blossom.1189 小时前
机器学习在智能建筑中的应用:能源管理与环境优化
人工智能·python·深度学习·神经网络·机器学习·机器人·sklearn
祁思妙想9 小时前
八股学习(三)---MySQL
数据库·学习·mysql