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

ops/2025/3/17 11:17:18/

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

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

确定爬取的信息内容:

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

爬取步骤:

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

一.发送请求

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

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


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

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

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

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

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

python"># 导包
import requestsfrom lxml import etreeheaders = {'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模块进行解析

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

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

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

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

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

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

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

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

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

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

python">    # 这里我们选择把 星期去掉 只要时间和具体的时间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 属性

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

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

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

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

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

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

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

python">    # 参与与感兴趣人数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
 构建循环 遍历

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

三.保存数据

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

python"># 主体代码如下
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 文件方式

python"># 导入模块
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()

保存到数据库

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

python"># 导包
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()

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

python">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.ppmy.cn/ops/166475.html

相关文章

Linux中安装MySQL

检查是否有MySQL服务并卸载 检查并卸载 在安装MySQL数据库之前,我们需要先检查一下当前Linux系统中,是否安装的有MySQL的相关服务(很多linux安装完毕之后,自带了低版本的mysql的依赖包),如果有&#xff0c…

【JavaEE进阶】@Transactional 详解

目录 🍃前言 🌲rollbackFor(异常回滚属性) 🚩rollbackFor属性 🚩noRollbackFor属性 🎄Isolation(事务隔离级别) 🚩MySQL事务的隔离级别 🚩Spring事务隔离级别 🎋Spring事务传…

【差分约束】 P3275 [SCOI2011] 糖果|省选-

本文涉及知识点 差分约束 P3275 [SCOI2011] 糖果 题目描述 幼儿园里有 N N N 个小朋友, lxhgww \text{lxhgww} lxhgww 老师现在想要给这些小朋友们分配糖果,要求每个小朋友都要分到糖果。但是小朋友们也有嫉妒心,总是会提出一些要求&…

嵌入式八股C语言---面向对象篇

面向对象与面向过程 面向过程 就是把整个业务逻辑分成多个步骤,每步或每一个功能都可以使用一个函数来实现面向对象 对象是类的实例化,此时一个类就内部有属性和相应的方法 封装 在C语言里实现封装就是实现一个结构体,里面包括的成员变量和函数指针,然后在构造函数中,为结构体…

Redis内存淘汰策略

Redis 是一种高性能的键值存储系统,广泛用于缓存、消息队列等场景。由于 Redis 数据存储在内存中,而内存资源有限,因此需要内存淘汰策略来管理内存的使用。Redis 提供了多种内存淘汰策略,可以根据不同的应用场景选择合适的策略。 …

Maven 的核心包

由于前端项目不是核心,阅读 nexus-public 源代码似乎绕远路了。nexus-oss 社区版主要就是集成 maven 的上传包、认证、包解析、包存储这几个核心功能,前端实现重新可以使用新的现代前端工具来提高生产力。故重新疏理一下 maven 的核心机制,即…

TCP/IP原理详细解析

前言 TCP/IP是一种面向连接,可靠的传输,传输数据大小无限制的。通常情况下,系统与系统之间的http连接需要三次握手和四次挥手,这个执行过程会产生等待时间。这方面在日常开发时需要注意一下。 TCP/IP 是互联网的核心协议族&…

R语言零基础系列教程-03-RStudio界面介绍与关键设置

代码、讲义、软件回复【R语言03】获取。 设置位置: 菜单栏 - Tools - Blobal Options 设置 通用设置 设置面板左侧General选项 版本选择: 一般只用一个版本即可 默认工作目录设置: 你希望RStudio打开时是基于哪个目录进行工作可以不设置, 因为脚本一般都是放置在特定项目路…