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

发布时间:2024年01月11日
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
文章来源:https://blog.csdn.net/m0_75089299/article/details/135532298
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。