写一段python语言,用于爬取携程丽江酒店民宿数据有 id,酒店,评论,价格,城市,区域,地址,距离,纬度,经度,评分,评价,环境,卫生,服务,设施,标签,并导出一个表格。并进行逐行注释
时间: 2025-04-05 10:15:10 浏览: 48
<<
以下是一段基于 Python 的携程丽江酒店民宿数据爬虫示例代码。该程序将使用 `requests` 和 `BeautifulSoup` 库抓取网页内容,并用 Pandas 将结果保存为 Excel 表格。
```python
import requests # 导入请求库用于发送HTTP请求
from bs4 import BeautifulSoup # 导入BeautifulSoup库解析HTML文档
import pandas as pd # 导入Pandas处理数据框
# 设置请求头模拟浏览器访问
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
}
def fetch_hotel_data(url):
try:
response = requests.get(url, headers=headers) # 发送GET请求获取页面信息
if response.status_code == 200: # 检查状态码是否正确(成功)
soup = BeautifulSoup(response.text, 'html.parser') # 使用BeautifulSoup解析响应文本
hotels = [] # 创建空列表存储所有酒店的数据字典
for item in soup.select('.hotel_item'): # 遍历每个酒店的容器节点
hotel_info = {} # 存储单个酒店的信息
hotel_info['id'] = item.get('data-hotel-id', '') or '' # 获取ID属性值或默认为空字符串
hotel_info['name'] = item.find('a', class_='hotel_name_link').text.strip() if item.find('a', class_='hotel_name_link') else ''
review_count_element = item.find('span', {'class': 'review_total'})
hotel_info['reviews'] = int(review_count_element.text.replace(',', '')) if review_count_element and review_count_element.text.isdigit() else 0
price_tag = item.find('span', class_='J_priceLowList')
hotel_info['price'] = float(price_tag.text[1:].replace(',', '')) if price_tag else None
city_area_container = item.find_all('p', class_='item_jt')[0]
address_parts = [part.strip() for part in city_area_container.stripped_strings] if city_area_container else []
hotel_info['city'], hotel_info['area'], hotel_info['address'] = (
address_parts + ['']*3)[:3] # 分割城市、区域、详细地址
distance_to_center = item.find('span', attrs={'title': True})
hotel_info['distance'] = distance_to_center.attrs['title'].strip() if distance_to_center else ''
latitude_longitude_text = item.get('data-latlng', '')
lat_lng_split = latitude_longitude_text.split(',')
hotel_info['latitude'] = float(lat_lng_split[0]) if len(lat_lng_split) >= 2 and lat_lng_split[0].isdigit() else None
hotel_info['longitude'] = float(lat_lng_split[1]) if len(lat_lng_split) >= 2 and lat_lng_split[1].isdigit() else None
score_tag = item.find('span', class_='score')
hotel_info['rating'] = float(score_tag.text.strip()) if score_tag else None
evaluation_tags = {tag['title']: tag.text.strip().split('%')[0] for tag in item.find_all('em')}
keys_map = {"综合": "overall", "环境": "environment", "卫生": "hygiene", "服务": "service", "设施": "facilities"}
for k, v in keys_map.items():
hotel_info[v] = evaluation_tags.get(k)
label_elements = item.find_all(class_="label")
labels_list = ','.join([ele.text.strip() for ele in label_elements])
hotel_info['labels'] = labels_list if labels_list else ""
hotels.append(hotel_info) # 添加当前遍历到的一个完整的酒店信息记录
return hotels
except Exception as e:
print(f"Error fetching data from URL {url}: {e}") # 错误捕获与打印
return []
if __name__ == "__main__":
target_url = 'https://hotels.ctrip.com/hotels/lijiang' # 示例URL,实际可能需要分页或多地区查询链接替换此部分逻辑
all_hotels_data = fetch_hotel_data(target_url)
df = pd.DataFrame(all_hotels_data) # 构建DataFrame结构化数据表
output_file_path = "./LijiangHotels.xlsx"
writer = pd.ExcelWriter(output_file_path, engine='xlsxwriter')
df.to_excel(writer, sheet_name='Sheet1', index=False) # 写入Excel文件指定的工作簿中
writer.save()
print("Data successfully exported to:", output_file_path) # 打印输出路径提示语句完成任务反馈
```
### 解释:
1. **导入必要的模块**:我们导入了三个主要模块——`requests`用于网络请求;`BeautifulSoup`用来解析 HTML 文档;以及 `pandas` 来生成并管理最终的结果表格。
2. **定义头部信息**:设置了一个包含 User-Agent 的请求头字段来模仿真实用户浏览行为,避免被服务器屏蔽。
3. **编写核心函数 `fetch_hotel_data()`**:接收目标网站的具体 url 参数后执行 HTTP 请求操作读取消息体再交由 BS 进行提取所需各项指标数值填充进字典型变量数组内返回给调用者继续下一步骤。
4. **主函数入口点检测及业务流程控制**: 先确定待采集的目标站点首页链接形式然后交给辅助方法去挖掘资料最后借助于第三方工具包转存成符合需求规格书里提到格式要求的数据集.
---
#### 注意事项:
- 实际运行时需根据具体携程网页结构调整选择器表达式;
- 数据量较大情况下要考虑加入翻页机制扩充样本覆盖范围;
- 如果遇到反爬措施如验证码,则需要用更复杂的手段例如 Selenium 或动态加载技术规避限制条件。
阅读全文