当前位置: 首页 > article >正文

爬虫基础之爬取豆瓣同城信息(保存为csv excel 数据库)

网站:长沙最近一周戏剧活动_豆瓣
温馨提示: 本案例仅供学习交流使用

本案例所使用的模块
requests(发送HTTP请求)pandas(数据保存模块)
lxml(用于解析数据模块)csv(用于保存为csv文件)
pymysql(用于操作数据库)parsel(解析数据的模块)

确定爬取的信息内容:

  • 戏剧的名称
  • 戏剧的时间
  • 戏剧的地点
  • 戏剧的费用
  • 参与与感兴趣人数

爬取步骤:

  1. 发送请求 模拟浏览器向服务器发送请求
  2. 解析数据 提取我们想要的数据
  3. 保存数据 对数据进行持久化保存 如csv excel mysql

一.发送请求

查看源代码 查看是否为静态数据

打开快捷键 Ctrl+F 输入我们想要爬取的数据


能够搜索到的为 静态数据  不能搜索到的为动态数据由服务器返回的 需要找到相关的返回接口

开始写代码  构建请求
复制浏览器中的网址  请求中的数据在 网络中的标头中查看

url = f'https://www.douban.com/location/changsha/events/week-drama'

F12 or 右击检查 点击网络 Ctrl+R 刷新接口  随便点击一个数据包

这里面包含我们所有的请求信息  比如请求方式 请求地址 UA cookie等
一般我们复制 UserAgent Referer cookie 这三个信息

# 导包
import requests

from lxml import etree

headers = {
    'user-agent':
        'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36 Edg/133.0.0.0',
    'referer':
        'https://www.douban.com/location/changsha/',
    'cookie':
        '你的cookie'
}
resp = requests.get(url, headers=headers)
print(resp.text)

打印我们请求到的网页信息 确认需要爬取的数据是否在里面

同样的在终端用Ctrl+F 快捷键打开搜索框 OK 数据在里头

二.解析数据

接着我们解析数据 使用lxml 中的etree模块进行解析

# 将页面解析成html
html = etree.HTML(resp.text)

然后我们分析网页页面  找到包含所有数据的标签 后续通过循环遍历提取
Explain: 用开发者工具上面的小箭头 去页面中分析结构

 我们取 ul class属性为events-list events-list-pic100 events-list-psmall 下面的li标签
 每一个li标签为一个戏剧

lis = html.xpath('//ul[@class="events-list events-list-pic100 events-list-psmall"]/li')

接着遍历循环 提取数据
name: 直接定位这个
itemprop="summary"的span标签 提取里面的文字

for li in lis:
    name = li.xpath('.//a/span[@itemprop="summary"]/text()')[0]
    # 提取出来的是个列表 我们取出来

time: class属性为event-time的li标签 提取里面的文本

打印查看文本 发现不是我们想要的格式  我们处理成想要的格式
将星期去掉 只保留日期和时间 去除换行符
将列表转换成字符串 去除空格 以一个空格分割

a = ''.join(li.xpath('.//li[@class="event-time"]/text()')).strip().split(' ')

打印出来看看结果  split 方法返回的是个列表通过取值得到我们想要的 之后做个字符串的拼接

    # 这里我们选择把 星期去掉 只要时间和具体的时间
    t = ''.join(li.xpath('.//li[@class="event-time"]/text()')).strip().split(' ')[0]
    i = ''.join(li.xpath('.//li[@class="event-time"]/text()')).strip().split(' ')[2]
    m = ''.join(li.xpath('.//li[@class="event-time"]/text()')).strip().split(' ')[-3]
    e = ''.join(li.xpath('.//li[@class="event-time"]/text()')).strip().split(' ')[-1]
    # 转换成我们想要的格式  中间以||字符隔开
    time = t + i + '||' + m + e


时间提取完毕
address:li标签下面meta标签中的itemprop=location 里面的content 属性

但我不要长沙两个字 后续提取的数据中都有 可以像之前那样处理 先转换成字符串 后分割索引取值 做个拼接 这里我一气呵成

    address = ''.join(li.xpath('.//li/meta[@itemprop="location"]/@content')).split(' ')[1] + ' ' + \
              ''.join(li.xpath('.//li/meta[@itemprop="location"]/@content')).split(' ')[2]

接着提取费用: class属性为fee下面的strong标签 里面的文本

去除里面的文字只保留数值

fee = ''.join(li.xpath('.//li[@class="fee"]/strong/text()')).replace('元起', '').replace('元', '')

最后感兴趣人数和参与人数 class属性为counts下面的第一个和第三个span标签 提取里面的文本

与之前的一样 删除文字 只保留数值

    # 参与与感兴趣人数
    participate = ''.join(li.xpath('.//p[@class="counts"]/span[1]/text()')).replace('人参加', '')
    interesting = ''.join(li.xpath('.//p[@class="counts"]/span[3]/text()')).replace('人感兴趣', '')

到此我们所有的数据提取完毕
多页采集的话 分析url请求地址的变化即可

第二页即第四页的数据 

 我们发现页码从0开始30结束 步长为10
 构建循环 遍历

for page in range(0, 31, 10):
    url = f'https://www.douban.com/location/changsha/events/week-drama?start={page}'

三.保存数据

先将我们的数据保存到字典当中 在外面定义一个空列表 后续将字典添加到列表中

# 主体代码如下
data = []
for page in range(0, 31, 10):
    url = f'https://www.douban.com/location/changsha/events/week-drama?start={page}'
    headers = {
        'user-agent':
            'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36 Edg/133.0.0.0',
        'referer':
            'https://www.douban.com/location/changsha/',
        'cookie':
            'bid=BY8EGmm9qc8; _vwo_uuid_v2=D1D9F5E9C68A518ED23DD0F263091E11E|05339352015c3656f34b21db6f6d7fac; _pk_id.100001.8cb4=273b64a736ae847b.1740225141.; dbcl2="287338786:YzuvHMiOWzs"; push_noty_num=0; push_doumail_num=0; __yadk_uid=PRahUgXe0eJLiRZgpFZjUYaLI78zwXW2; __utmv=30149280.28733; _ga_RXNMP372GL=GS1.1.1741225615.2.0.1741225615.60.0.0; ck=qsD8; __utmc=30149280; __utmz=30149280.1741595670.20.11.utmcsr=cn.bing.com|utmccn=(referral)|utmcmd=referral|utmcct=/; frodotk_db="5213e2611a4c65c4f63ba7234ee5314c"; _ga=GA1.2.1489580265.1740970320; _gid=GA1.2.1344269174.1741598633; _ga_Y4GN1R87RG=GS1.1.1741598632.1.0.1741598634.0.0.0; loc-last-index-location-id="118267"; ll="118267"; ap_v=0,6.0; _pk_ref.100001.8cb4=%5B%22%22%2C%22%22%2C1741606351%2C%22https%3A%2F%2Fntp.msn.cn%2F%22%5D; _pk_ses.100001.8cb4=1; __utma=30149280.1636982792.1735051587.1741598189.1741606351.22; __utmt=1; __utmb=30149280.4.10.1741606351'
    }
    
    resp = requests.get(url, headers=headers)
    html = etree.HTML(resp.text)
    lis = html.xpath('//ul[@class="events-list events-list-pic100 events-list-psmall"]/li')
    
    dit = {}
    for li in lis:
        name = li.xpath('.//a/span[@itemprop="summary"]/text()')[0]
        # 这里我们选择把 星期去掉 只要时间和具体的时间
        t = ''.join(li.xpath('.//li[@class="event-time"]/text()')).strip().split(' ')[0]
        i = ''.join(li.xpath('.//li[@class="event-time"]/text()')).strip().split(' ')[2]
        m = ''.join(li.xpath('.//li[@class="event-time"]/text()')).strip().split(' ')[-3]
        e = ''.join(li.xpath('.//li[@class="event-time"]/text()')).strip().split(' ')[-1]
        # 转换成我们想要的格式
        time = t + i + '||' + m + e
        # 另外一种方法 处理时间
        # n = li.xpath('.//li[@class="event-time"]/text()')[1].replace('\n', '').replace(' ','')
        # address = ''.join(li.xpath('//ul[@class="event-meta"]/li[2]/text()')).replace('\n','').replace(' ','')
        # 电影费用  并只保留数值
        # 将前面的长沙去掉
        address = ''.join(li.xpath('.//li/meta[@itemprop="location"]/@content')).split(' ')[1] + ' ' + \
                  ''.join(li.xpath('.//li/meta[@itemprop="location"]/@content')).split(' ')[2]

        fee = ''.join(li.xpath('.//li[@class="fee"]/strong/text()')).replace('元起', '').replace('元', '')
        # 参与与感兴趣人数
        participate = ''.join(li.xpath('.//p[@class="counts"]/span[1]/text()')).replace('人参加', '')
        interesting = ''.join(li.xpath('.//p[@class="counts"]/span[3]/text()')).replace('人感兴趣', '')

        dit = {
            'name': name,
            'time': time,
            'fee': fee,
            'participate': participate,
            'interesting': interesting,
            'address': address,
        }
        data.append(dit)
pd.DataFrame(data).to_excel('city.xlsx', index=False)

以上为通过pandas保存为excel表格

保存为csv 文件方式

# 导入模块
import csv
#调用字典写入方法 写入文件  保存为csv的格式编码为utf-8-sig 不然会出现乱码
csv_writer = csv.DictWriter(open('city_csv.csv', 'w', encoding='utf-8-sig', newline=''),
                fieldnames=['name', 'time', 'fee', 'participate', 'interesting', 'address'])
# fieldnames 定义标头
# 写入表头
csv_writer.writeheader()

保存到数据库

前提需要建库建表 定义字段

# 导包
import pymysql

# 获取连接
connect = pymysql.connect(user='root',
                          password="112233",
                          host='localhost',
                          database='douban', )
# 拿到游标
cursor = connect.cursor()

# 准备sql语句
sql = 'insert into city values(%s,%s,%s,%s,%s,%s)'
# 执行sql
cursor.executemany(sql, [(name, time, fee, participate, interesting, address)])
# 提交事务
connect.commit()

本次案例的所有源代码  供大家交流学习使用

import requests
from lxml import etree
import pandas as pd
import csv
import pymysql

# csv_writer = csv.DictWriter(open('city_csv.csv', 'w', encoding='utf-8-sig', newline=''),
#                fieldnames=['name', 'time', 'fee', 'participate', 'interesting', 'address'])
# csv_writer.writeheader()

# 获取连接
connect = pymysql.connect(user='root',
                          password="112233",
                          host='localhost',
                          database='douban', )
cursor = connect.cursor()

data = []
for page in range(0, 31, 10):
    url = f'https://www.douban.com/location/changsha/events/week-drama?start={page}'
    headers = {
        'user-agent':
            'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36 Edg/133.0.0.0',
        'referer':
            'https://www.douban.com/location/changsha/',
        'cookie':
            'bid=BY8EGmm9qc8; _vwo_uuid_v2=D1D9F5E9C68A518ED23DD0F263091E11E|05339352015c3656f34b21db6f6d7fac; _pk_id.100001.8cb4=273b64a736ae847b.1740225141.; dbcl2="287338786:YzuvHMiOWzs"; push_noty_num=0; push_doumail_num=0; __yadk_uid=PRahUgXe0eJLiRZgpFZjUYaLI78zwXW2; __utmv=30149280.28733; _ga_RXNMP372GL=GS1.1.1741225615.2.0.1741225615.60.0.0; ck=qsD8; __utmc=30149280; __utmz=30149280.1741595670.20.11.utmcsr=cn.bing.com|utmccn=(referral)|utmcmd=referral|utmcct=/; frodotk_db="5213e2611a4c65c4f63ba7234ee5314c"; _ga=GA1.2.1489580265.1740970320; _gid=GA1.2.1344269174.1741598633; _ga_Y4GN1R87RG=GS1.1.1741598632.1.0.1741598634.0.0.0; loc-last-index-location-id="118267"; ll="118267"; ap_v=0,6.0; _pk_ref.100001.8cb4=%5B%22%22%2C%22%22%2C1741606351%2C%22https%3A%2F%2Fntp.msn.cn%2F%22%5D; _pk_ses.100001.8cb4=1; __utma=30149280.1636982792.1735051587.1741598189.1741606351.22; __utmt=1; __utmb=30149280.4.10.1741606351'
    }

    resp = requests.get(url, headers=headers)
    html = etree.HTML(resp.text)
    lis = html.xpath('//ul[@class="events-list events-list-pic100 events-list-psmall"]/li')

    dit = {}
    for li in lis:
        name = li.xpath('.//a/span[@itemprop="summary"]/text()')[0]
        # 这里我们选择把 星期去掉 只要时间和具体的时间
        t = ''.join(li.xpath('.//li[@class="event-time"]/text()')).strip().split(' ')[0]
        i = ''.join(li.xpath('.//li[@class="event-time"]/text()')).strip().split(' ')[2]
        m = ''.join(li.xpath('.//li[@class="event-time"]/text()')).strip().split(' ')[-3]
        e = ''.join(li.xpath('.//li[@class="event-time"]/text()')).strip().split(' ')[-1]
        # 转换成我们想要的格式
        time = t + i + '||' + m + e
        # 另外一种方法 处理时间
        # n = li.xpath('.//li[@class="event-time"]/text()')[1].replace('\n', '').replace(' ','')
        # address = ''.join(li.xpath('//ul[@class="event-meta"]/li[2]/text()')).replace('\n','').replace(' ','')
        # 电影费用  并只保留数值
        # 将前面的长沙去掉
        address = ''.join(li.xpath('.//li/meta[@itemprop="location"]/@content')).split(' ')[1] + ' ' + \
                  ''.join(li.xpath('.//li/meta[@itemprop="location"]/@content')).split(' ')[2]

        fee = ''.join(li.xpath('.//li[@class="fee"]/strong/text()')).replace('元起', '').replace('元', '')
        # 参与与感兴趣人数
        participate = ''.join(li.xpath('.//p[@class="counts"]/span[1]/text()')).replace('人参加', '')
        interesting = ''.join(li.xpath('.//p[@class="counts"]/span[3]/text()')).replace('人感兴趣', '')

        dit = {
            'name': name,
            'time': time,
            'fee': fee,
            'participate': participate,
            'interesting': interesting,
            'address': address,
        }
        # data.append(dit)
        # csv_writer.writerow(dit)

        sql = 'insert into city values(%s,%s,%s,%s,%s,%s)'
        cursor.executemany(sql, [(name, time, fee, participate, interesting, address)])
        connect.commit()

    # pd.DataFrame(data).to_excel('city.xlsx', index=False)

本次的案例到此结束 感谢大家的观看  您的点赞和关注是我更新的动力

也可以看看我之前的文章希望对你有帮助
 


http://www.kler.cn/a/585471.html

相关文章:

  • 【计算机网络】第八版和第七版的主要区别,附PDF
  • Chatbox通过百炼调用DeepSeek
  • Qt项目中集成第三方模块的.pri文件
  • hadoop集群配置-ssh无密登陆
  • 数据结构-栈(详解)
  • 【瞎折腾/Dify】使用docker离线部署Dify
  • Unity中解锁图片像素点,动态闭合轨迹检测
  • 【2025】基于python+django的慢性病健康管理系统(源码、万字文档、图文修改、调试答疑)
  • LeeCode题库第643题
  • [目标检测] 训练之前要做什么
  • 【深度学习|目标检测】YOLO系列anchor-based原理详解
  • SpringBoot旅游管理系统的设计与实现
  • [Java]栈 虚拟机栈 栈帧讲解
  • 蓝桥每日打卡--查找有序数组中的目标值
  • kotlin与MVVM的结合使用总结(二)
  • 工业三防平板AORO-P300 Ultra,开创铁路检修与调度数字化新范式
  • python多种数据类型输出为Excel文件
  • 【模块化编程】数据标签 转 独热编码
  • SSL 和 TLS 认证
  • 汉朔科技业绩高增长:市占率国内外遥遥领先,核心技术创新强劲