Python爬虫实战:利用代理IP爬取某瓣电影排行榜并写入Excel(附上完整源码)

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
简介: Python爬虫实战:利用代理IP爬取某瓣电影排行榜并写入Excel(附上完整源码)

1. 爬虫和代理IP的关系

爬虫是指通过编写程序自动获取互联网上的信息的技术。爬虫可以模拟人的行为,在网页上浏览、点击、输入数据等,从而获取网页上的各种信息,如文本、图片、视频等。爬虫可以用于各种目的,如搜索引擎的索引、数据分析、信息监测等。

代理IP是指通过中间服务器转发网络请求的技术。在爬虫中,使用代理IP可以隐藏真实的访问源,防止被目标网站封禁或限制访问。代理IP可以分为正向代理和反向代理。正向代理是由客户端主动使用代理服务器来访问目标网站,而反向代理是目标网站使用代理服务器来处理客户端的请求。

图片.png

2. 使用代理IP的好处

使用代理IP可以带来以下好处:

  1. 隐藏真实的访问源,保护个人或机构的隐私和安全。
  2. 绕过目标网站的访问限制,如IP封禁、地区限制等。
  3. 分散访问压力,提高爬取效率和稳定性。
  4. 收集不同地区或代理服务器上的数据,用于数据分析和对比。

然而,使用代理IP也存在一些挑战和注意事项:

  1. 代理IP的质量参差不齐,有些代理服务器可能不稳定、速度慢或存在安全风险。
  2. 一些目标网站会检测和封禁常用的代理IP,需要不断更换和验证代理IP的可用性。
  3. 使用代理IP可能增加网络请求的延迟和复杂性,需要合理配置和调整爬虫程序。
  4. 使用代理IP需要遵守相关法律法规和目标网站的使用规则,不得进行非法活动或滥用代理IP服务。

博主这里使用的亮数据家的动态代理IP,IP质量很高个人感觉还不错,公司用户可以免费使用:点击试用

图片.png

3. 爬取目标

这次爬虫实战的目标是某瓣电影Top250排行榜,爬取的字段:排名、电影名、评分、评价人数、制片国家、电影类型、上映时间、主演、影片链接

图片.png

预期效果写入Excel:
图片.png

4. 准备工作

Python:3.10

编辑器:PyCharm

第三方模块,自行安装:

pip install requests # 网页数据爬取
pip install pandas # 数据处理
pip install xlwt # 写入Excel
pip install lxml # 提取网页数据

5. 爬虫实现

5.1 获取代理IP

1、打开亮数据的官网,点击立刻使用:点击试用

图片.png

2、输入账号密码注册账号:

图片.png

3、注册后以后点击查看代理IP产品:

图片.png

4、选择适合自己ide产品,如果你使用公司邮件注册,可以找客服开通免费试用:

图片.png

5、获取代理IP后通过proxies参数添加代理发送请求,案例代码:

proxies = {
  "http": "http://IP地址:端口号",   # http型
  "https": "https://IP地址:端口号"   # https型
}
response = requests.get(url,headers=headers,proxies=proxies)

5.2 导入模块

import re # 正则,用于提取字符串
import pandas as pd # pandas,用于写入Excel文件
import requests  # python基础爬虫库
from lxml import etree  # 可以将网页转换为Elements对象
import time  # 防止爬取过快可以睡眠一秒

5.3 设置翻页

首先我们来分析一下网站的翻页,一共有10页:

图片.png

第一页主页为:

https://movie.douban.com/top250?start=0&filter=

第二页:

https://movie.douban.com/top250?start=25&filter=

第三页:

https://movie.douban.com/top250?start=50&filter=

可以看出每页只有start=后面的参数每次上涨25,所以用循环来构造10页网页链接:

def main():
    data_list = [] # 空列表用于存储每页获取到的数据
    for i in range(10):
        url = 'https://movie.douban.com/top250?start='+str(i*25)+'&filter='

5.4 发送请求

这里我们创建一个get_html_str(url)函数传入网页url链接,通过添加请求头和代理IP发送请求获取网页源码(注意:这里代理IP这里需要看5.1 获取代理IP自己去获取,博主的已过期):

def get_html_str(url):
    """发送请求,获取响应"""
    # 请求头模拟浏览器
    headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36'}

    # 添加代理IP(这里代理IP这里需要看`5.1 获取代理IP`自己去获取,博主的已过期)
    proxies = {
        "http": "http://183.134.17.12:9181",
    }
    # 添加请求头和代理IP发送请求
    response = requests.get(url,headers=headers,proxies=proxies)
    # 获取网页源码
    html_str = response.content.decode()
    # 返回网页源码
    return html_str

5.5 提取数据

当我们拿到网页源码后,创建一个get_data(html_str,data_list)函数传入html_str也就是网页源码、data_list用于存储数据,就可以使用xpath开始解析数据了

1、分析网页结构,可以看到每一个电影都在ol标签下的li标签下:

图片.png

2、然后我们看li标签的数据是否完整,可以看到我们需要的字段都有:

图片.png

3、接下来开始写解析代码:

def get_data(html_str, data_list):
    """提取数据写入列表"""
    # 将html字符串转换为etree对象方便后面使用xpath进行解析
    html_data = etree.HTML(html_str)
    # 利用xpath取到所有的li标签
    li_list = html_data.xpath("//ol[@class='grid_view']/li")
    # 打印一下li标签个数看是否和一页的电影个数对得上
    print(len(li_list))  # 输出25,没有问题
    # 遍历li_list列表取到某一个电影的对象
    for li in li_list:
        # 用xpath获取每一个字段信息
        # 排名
        ranking = li.xpath(".//div[@class='pic']/em/text()")[0]
        # 电影名
        title = li.xpath(".//div[@class='hd']/a/span[1]/text()")[0]
        # 评分
        score = li.xpath(".//span[@class='rating_num']/text()")[0]
        # 评价人数
        evaluators_number = li.xpath(".//div[@class='star']/span[4]/text()")[0]
        evaluators_number = evaluators_number.replace('人评价', '')  # 将'人评价'替换为替换为空,更美观
        # 导演、主演
        str1 = li.xpath(".//div[@class='bd']/p[1]//text()")[0]
        # 利用正则提取导演名
        try:
            director = re.findall("导演: (.*?)主演", str1)[0]
            director = re.sub('\xa0', '', director)
        except:
            director = None
        # 利用正则提取主演
        try:
            performer = re.findall("主演: (.*)", str1)[0]
            performer = re.sub('\xa0', '', performer)
        except:
            performer = None
        # 上映时间、制片国家、电影类型都在这里标签下
        str2 = li.xpath(".//div[@class='bd']/p[1]//text()")[1]
        #
        try:
            # 通过斜杠进行分割
            str2_list = str2.split(' / ')
            # 年份
            year = re.sub('[\n ]', '', str2_list[0])
            # 制片国家
            country = str2_list[1]
            # 影片类型
            type = re.sub('[\n ]', '', str2_list[2])
        except:
            year = None
            country = None
            type = None
        url = li.xpath(".//div[@class='hd']/a/@href")[0]
        print({'排名': ranking, '电影名': title, '评分': score, '评价人数': evaluators_number, '导演': director,
               '主演': performer, '年份': year, '制片国家': country, '影片类型': type, '影片主页链接': url})
        data_list.append(
            {'排名': ranking, '电影名': title, '评分': score, '评价人数': evaluators_number, '导演': director,
             '主演': performer, '年份': year, '制片国家': country, '影片类型': type, '影片主页链接': url})

运行结果:

图片.png

5.6 保存数据

当我们提取完数据以后就可以写入用pandas写入Excel表格中,创建into_excel(data_list)函数,将存储数据的data_list列表作为参数传入,然后用pandas的to_excel函数写入excel表格:

def into_excel(data_list):
    # 创建DataFrame对象
    df = pd.DataFrame(data_list)
    # 写入excel文件
    df.to_excel('电影Top250排行.xlsx')

5.7 调用主函数

第一步设置翻页,然后获取网页源码,接着提取数据,限制爬取的速度,最后写入Excel文件

def main():
    data_list = []  # 空列表用于存储每页获取到的数据
    # 1. 设置翻页
    for i in range(10):
        url = 'https://movie.douban.com/top250?start=' + str(i * 25) + '&filter='
        # 2. 获取网页源码
        html_str = get_html_str(url)
        # 3. 提取数据
        get_data(html_str, data_list)
        # 4. 限制爬取的速度
        time.sleep(5)
    # 5. 写入excel
    into_excel(data_list)

5.8 完整源码

这里附上完整源码(注意:get_html_str(url)函数中的代理IP这里需要看5.1 获取代理IP自己去获取,博主的已过期),然后直接运行程序即可:

import re # 正则,用于提取字符串
import pandas as pd # pandas,用于写入Excel文件
import requests  # python基础爬虫库
from lxml import etree  # 可以将网页转换为Elements对象
import time  # 防止爬取过快可以睡眠一秒


def get_html_str(url):
    """发送请求,获取响应"""
    # 请求头模拟浏览器
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36'}

    # 添加代理IP(这里代理IP这里需要看`5.1 获取代理IP`自己去获取,博主的已过期)
    proxies = {
        "http": "http://183.134.17.12:9181",
    }
    # 添加请求头和代理IP发送请求
    response = requests.get(url, headers=headers, proxies=proxies)  #
    # 获取网页源码
    html_str = response.content.decode()
    # 返回网页源码
    return html_str


def get_data(html_str, data_list):
    """提取数据写入列表"""
    # 将html字符串转换为etree对象方便后面使用xpath进行解析
    html_data = etree.HTML(html_str)
    # 利用xpath取到所有的li标签
    li_list = html_data.xpath("//ol[@class='grid_view']/li")
    # 打印一下li标签个数看是否和一页的电影个数对得上
    print(len(li_list))  # 输出25,没有问题
    # 遍历li_list列表取到某一个电影的对象
    for li in li_list:
        # 用xpath获取每一个字段信息
        # 排名
        ranking = li.xpath(".//div[@class='pic']/em/text()")[0]
        # 电影名
        title = li.xpath(".//div[@class='hd']/a/span[1]/text()")[0]
        # 评分
        score = li.xpath(".//span[@class='rating_num']/text()")[0]
        # 评价人数
        evaluators_number = li.xpath(".//div[@class='star']/span[4]/text()")[0]
        evaluators_number = evaluators_number.replace('人评价', '')  # 将'人评价'替换为替换为空,更美观
        # 导演、主演
        str1 = li.xpath(".//div[@class='bd']/p[1]//text()")[0]
        # 利用正则提取导演名
        try:
            director = re.findall("导演: (.*?)主演", str1)[0]
            director = re.sub('\xa0', '', director)
        except:
            director = None
        # 利用正则提取主演
        try:
            performer = re.findall("主演: (.*)", str1)[0]
            performer = re.sub('\xa0', '', performer)
        except:
            performer = None
        # 上映时间、制片国家、电影类型都在这里标签下
        str2 = li.xpath(".//div[@class='bd']/p[1]//text()")[1]
        #
        try:
            # 通过斜杠进行分割
            str2_list = str2.split(' / ')
            # 年份
            year = re.sub('[\n ]', '', str2_list[0])
            # 制片国家
            country = str2_list[1]
            # 影片类型
            type = re.sub('[\n ]', '', str2_list[2])
        except:
            year = None
            country = None
            type = None
        url = li.xpath(".//div[@class='hd']/a/@href")[0]
        print({'排名': ranking, '电影名': title, '评分': score, '评价人数': evaluators_number, '导演': director,
               '主演': performer, '年份': year, '制片国家': country, '影片类型': type, '影片主页链接': url})
        data_list.append(
            {'排名': ranking, '电影名': title, '评分': score, '评价人数': evaluators_number, '导演': director,
             '主演': performer, '年份': year, '制片国家': country, '影片类型': type, '影片主页链接': url})


def into_excel(data_list):
    # 创建DataFrame对象
    df = pd.DataFrame(data_list)
    # 写入excel文件
    df.to_excel('电影Top250排行.xlsx')


def main():
    data_list = []  # 空列表用于存储每页获取到的数据
    # 1. 设置翻页
    for i in range(10):
        url = 'https://movie.douban.com/top250?start=' + str(i * 25) + '&filter='
        # 2. 获取网页源码
        html_str = get_html_str(url)
        # 3. 提取数据
        get_data(html_str, data_list)
        # 4. 限制爬取的速度
        time.sleep(5)
    # 5. 写入excel
    into_excel(data_list)


if __name__ == "__main__":
    main()

程序运行完毕后生成excel文件:

图片.png

6. 获取免费定制数据

上面我们讲了如何利用Python爬虫获取数据,博主估摸着还是有很多小伙伴不知道怎么写爬虫代码,博主使用亮数据代理IP时偶然发现竟然还有免费的数据集可以下载,不会爬虫和想偷懒的小伙伴可以省事了:

1、进入亮数据官网,点击网络数据,然后点击获取获取免费样本:点击免费领取
图片.png

2、输入好个人信息和需要的数据集名称后,点击提交:

图片.png

3、然后等着客服免费送数据集就可以啦,欧耶:

图片.png

相关文章
|
3天前
|
数据采集 算法 数据挖掘
10余位大佬+10余年经验的结晶:Python数据分析与挖掘实战
LinkedIn 对全球超过3.3亿用户的工作经历和技能进行分析后得出,目前最炙手可热的25 项技能中,数据挖掘排名第一。那么数据挖掘是什么? 数据挖掘是从大量数据(包括文本)中挖掘出隐含的、先前未知的、对决策有潜在价值的关系、模式和趋势,并用这些知识和规则建立用于决策支持的模型,提供预测性决策支持的方法、工具和过程。数据挖掘有助于企业发现业务的趋势,揭示已知的事实,预测未知的结果,因此“数据挖掘”已成为企业保持竞争力的必要方法。 今天给小伙伴们分享的Python数据分析与数据挖掘手册是10余位数据挖掘领域资深专家和科研人员,10余年大数据挖掘咨询与实施经验结晶。从数据挖掘的应用出发,以电力、
10余位大佬+10余年经验的结晶:Python数据分析与挖掘实战
|
2天前
|
数据采集 算法 数据挖掘
10余位大佬+10余年经验的结晶:Python数据分析与挖掘实战
LinkedIn 对全球超过3.3亿用户的工作经历和技能进行分析后得出,目前最炙手可热的25 项技能中,数据挖掘排名第一。那么数据挖掘是什么? 数据挖掘是从大量数据(包括文本)中挖掘出隐含的、先前未知的、对决策有潜在价值的关系、模式和趋势,并用这些知识和规则建立用于决策支持的模型,提供预测性决策支持的方法、工具和过程。数据挖掘有助于企业发现业务的趋势,揭示已知的事实,预测未知的结果,因此“数据挖掘”已成为企业保持竞争力的必要方法。 今天给小伙伴们分享的Python数据分析与数据挖掘手册是10余位数据挖掘领域资深专家和科研人员,10余年大数据挖掘咨询与实施经验结晶。从数据挖掘的应用出发,以电力、
|
4天前
|
运维 Devops 测试技术
一个人活成一个团队:python的django项目devops实战
DevOps通过自动化的流程,使得构建、测试、发布软件能够更加地快捷、频繁和可靠。本文通过一个python的django个人博客应用进行了DevOps的实战,通过DevOps拉通开发和运维,通过应用云效的DevOps平台实现自动化“软件交付”的流程,使得构建、测试、发布软件能够更加地快捷、频繁和可靠,提交研发交付效率。作为个人项目也是可以应用devops提高效率。
16 3
|
7天前
|
存储 JSON 数据可视化
python实战|1000位小姐姐照制作照片墙,刷新你三观的颜值!
python实战|1000位小姐姐照制作照片墙,刷新你三观的颜值!
19 2
|
13天前
|
数据采集 XML 前端开发
Python爬虫实战:利用代理IP爬取百度翻译
Python 爬虫实战:利用代理 IP 爬取百度翻译
|
16天前
|
机器学习/深度学习 算法 Python
决策树下的智慧果实:Python机器学习实战,轻松摘取数据洞察的果实
【8月更文挑战第3天】在数据的海洋中探寻真知,决策树犹如智慧之树,以其直观易懂的强大功能,引领我们逐步缩小决策范围,轻松获取数据洞察。本篇将带您踏上Python机器学习之旅,从理解决策树为何受青睐开始,通过scikit-learn库实现鸢尾花数据集分类,解析其决策机制,并掌握调参技巧,最终优化模型性能,共同摘取数据科学的甜美果实。
27 1
|
14天前
|
Linux 开发者 iOS开发
Python系统调用实战:如何在不同操作系统间游刃有余🐟
【8月更文挑战第5天】Python系统调用实战展示了如何轻松应对跨平台挑战。通过`os`与`pathlib`模块处理文件系统操作,如创建目录及获取用户主目录,自动适配不同操作系统的路径格式。利用`subprocess`模块执行外部命令,智能选择`ls`或`dir`等系统特定指令。借助Tkinter创建图形用户界面,实现一次编写到处运行的目标。这些技巧让开发者专注于应用逻辑,简化跨平台开发流程。
9 0
|
15天前
|
监控 测试技术 数据库
从慢如蜗牛到飞一般的感觉!Python性能测试实战,JMeter&Locust助你加速🏃‍♂️
【8月更文挑战第4天】曾几何时,Python应用响应缓慢,用户体验大打折扣。但有了JMeter与Locust,一切迎刃而解!JMeter,跨平台的性能魔法师,助你轻松模拟高并发场景,揪出性能瓶颈。Locust,则是Python世界的性能小能手,以简洁的Python代码实现高效测试。两者联手,让你的应用摆脱蜗牛速度,迎接流畅体验的新篇章!
15 0
|
7天前
|
算法 程序员 开发工具
百万级Python讲师又一力作!Python编程轻松进阶,豆瓣评分8.1
在学习Python的旅程中你是否正在“绝望的沙漠”里徘徊? 学完基础教程的你,是否还在为选择什么学习资料犹豫不决,不知从何入手,提高自己?
百万级Python讲师又一力作!Python编程轻松进阶,豆瓣评分8.1