当前位置: 首页> 文旅> 艺术 > Scrapy 爬取旅游景点相关数据(六):代理使用

Scrapy 爬取旅游景点相关数据(六):代理使用

时间:2025/7/11 17:35:18来源:https://blog.csdn.net/roccreed/article/details/140793769 浏览次数:0次

本期内容:(1)继续完善评论数据的爬取 (2) 代理的使用

1 创建数据库表

上期我们只打印了爬取到的数据,并没有入库,保存到数据,先执行以下SQL:

CREATE TABLE tb_comment (id INT AUTO_INCREMENT PRIMARY KEY COMMENT '自增主键',tid VARCHAR(255) COMMENT '景点ID',username VARCHAR(255) COMMENT '评论的用户名',avatar VARCHAR(255) COMMENT '评论用户的头像 URL',comments TEXT COMMENT '评论的内容',label VARCHAR(20) COMMENT '情感分析分类',score decimal(10,2) comment '情感分析得分'
) COMMENT '评论数据表';

后续我们要做情感分析,所以预留了情感分析的字段。

2 编写管道

上一期已经把解析的代码写的差不多了,遗留了管道部分未写,下面补全:

# 保存mysql 景点评论
class TourCommentPipeline:def __init__(self, crawler):self.crawler = crawler# 连接 MySQL 数据库self.db = pymysql.connect(host=self.crawler.settings.get('DB_HOST'),user=self.crawler.settings.get('DB_USER'),password=self.crawler.settings.get('DB_PASS'),database=self.crawler.settings.get('DB_DATABASE'),charset=self.crawler.settings.get('DB_CHARSET'))self.cursor = self.db.cursor()@classmethoddef from_crawler(cls, crawler):return cls(crawler)def process_item(self, item, spider):# 检查数据是否已存在sql = "SELECT COUNT(*) FROM tb_comment WHERE tid = %s and username= %s "self.cursor.execute(sql, (item["tid"],  item['username']))count = self.cursor.fetchone()[0]if count > 0:spider.log(f"Data already exists: {item['tid'], item['username']}")return item# 插入新数据sql = ("INSERT INTO tb_comment (tid, username, avatar, comments) ""VALUES (%s, %s, %s, %s)")values = (item["tid"],item["username"],item["avatar"],item["comments"],)try:self.cursor.execute(sql, values)self.db.commit()self.total_items += 1spider.log(f"Saved data: {item['username']}")except pymysql.Error as e:self.db.rollback()spider.log(f"Error saving data: {item['username']} - {e}")return itemdef close_spider(self, spider):self.cursor.close()self.db.close()

3 测试结果

测试爬取的结果是不太给力的,基本上爬取没多少时间,就会报ConnectionRefusedError 的异常,原因应该是目标网站已经监测到我们的爬取行为了。

中间尝试了调低scrapy的并发量和增加每次下载的延时,在settings.py里

# Configure maximum concurrent requests performed by Scrapy (default: 16)
CONCURRENT_REQUESTS = 2  #并发2,甚至我试过1,然并卵
# Configure a delay for requests for the same website (default: 0)
# See https://docs.scrapy.org/en/latest/topics/settings.html#download-delay
# See also autothrottle settings and docs
DOWNLOAD_DELAY = 2  # 这个调低了,爬取速度巨慢好吗?

修改这个参数会降低爬取效率,而且并不一定能绕开请求拒绝的问题(再说如果爬取非常慢还有啥意义呢 😭 )

4 代理 😎

为了改变这个局面,在爬虫中需要加入代理机制,本期的话先给出提取代理服务器的代码并且做一个简单的访问测试。

首先需要一个代理的来源,这里找了一家服务商(具体名字不提供了),提取的代码如下:

def get_proxy(key, num):response = requests.get(f'https://******/get?key={key}&num={num}')if response.status_code == 200:proxies = []ip_pool = []proxy_data = response.json()# 假设返回的JSON数据中包含代理IP地址# 例如: {"proxy": "http://123.45.67.89:8080"}for p in proxy_data['data']:# print(p)proxies.append(p['server'])   #要用的是这个地址ip_pool.append(p['proxy_ip'])print('ip_pool:', ip_pool)return proxieselse:return []

返回的是一个代理服务器的列表,例如: [ 123.45.67.89:8080]

然后怎么测试这个呢? 可以写如下demo代码:

 
# 测试通过代理访问网站
import requests
def test_proxy_request():ip = "http://123.45.67.89:8080"# 代理设置proxy = {'http': 'http://代理服务商可能提供的KEY,密码之类的前缀' + ip,}# 要访问的目标 URLurl = 'https://place.qyer.com/poi/V2UJYlFiBzRTZVI7Cmk/review/'try:# 通过代理发送请求response = requests.get(url, proxies=proxy, timeout=10)# 检查返回状态码if response.status_code == 200:print("访问成功,返回状态码为200")else:print(f"访问失败,返回状态码为{response.status_code}")except requests.exceptions.RequestException as e:print(f"请求出错: {e}")# 运行测试
test_proxy_request()

那在scrapy中怎么使用代理,也是非常简单,只需要修改precess_request方法:

    def process_request(self, request, spider):if self.proxies == []:self.update_proxies()proxy = random.choice(self.proxies)# print(f"目前使用的代理是:http://{proxy}")request.meta['proxy'] = f"http://{self.user}:{self.passw}@{proxy}"  # 这个是我使用的代理的拼写方法,不同的服务商可能不同,这行需要修改!

更新代理池的方法,这里每次更新16个代理地址,可以根据实际情况调整:

    def update_proxies(self):self.proxies = get_proxy(self.user, 16)

5 小结

本期通过设置代理实现了对评论数据的爬取和入库,不过实际使用过程中,代理池是需要更新的,还有很多异常情况需要处理,需要优化的细节很多,请关注本专栏,麦麦会在后续的博文中给大家带来。

关键字:Scrapy 爬取旅游景点相关数据(六):代理使用

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: