Python如何爬取美团美食数据

发布时间:2021-11-25 14:59:08 作者:小新
来源:亿速云 阅读:317
# Python如何爬取美团美食数据

## 一、爬取美团数据的背景与挑战

美团作为中国领先的生活服务电子商务平台,积累了海量的餐饮商户数据,包括店铺评分、用户评价、人均消费等关键信息。这些数据对于市场分析、竞品调研和商业决策具有重要价值。然而,美团数据的爬取面临三大技术难点:

1. **反爬机制严格**:美团采用动态渲染、请求加密、IP限制等多重防护
2. **数据结构复杂**:页面元素嵌套层级深,数据分散在多个异步接口中
3. **动态参数生成**:关键请求需要携带随时间变化的token和签名

## 二、技术方案设计

### 2.1 整体架构
```mermaid
graph TD
    A[启动爬虫] --> B[模拟登录/获取Cookies]
    B --> C[构造请求参数]
    C --> D[发送HTTP请求]
    D --> E{响应成功?}
    E -->|是| F[解析数据]
    E -->|否| G[异常处理]
    F --> H[数据存储]
    G --> C

2.2 核心组件选型

组件类型 推荐方案 替代方案
请求库 requests + selenium aiohttp
解析库 BeautifulSoup + parsel pyquery
动态渲染 Playwright Puppeteer
代理服务 芝麻代理/快代理 自建IP池
数据存储 MongoDB MySQL/CSV

三、详细实现步骤

3.1 环境准备

# 安装依赖库
pip install requests playwright beautifulsoup4 pymongo

# 初始化Playwright
playwright install

3.2 页面分析关键点

  1. 接口逆向工程

    • 使用Chrome开发者工具捕获XHR请求
    • 重点分析包含poishop等关键词的接口
    • 典型数据接口示例:
      
      https://www.meituan.com/meishi/api/poi/getPoiList?cityId=1&page=1
      
  2. 参数加密分析

    • 定位到关键加密函数_genToken()
    function _genToken() {
       return Math.random().toString(36).substr(2) + 
              Date.now().toString(36);
    }
    

3.3 完整爬虫代码实现

import requests
from bs4 import BeautifulSoup
from urllib.parse import urlencode
import time
import hashlib

class MeituanSpider:
    def __init__(self):
        self.headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) ...',
            'Referer': 'https://www.meituan.com/meishi/'
        }
        self.proxy = {'http': 'http://127.0.0.1:1080'}
        
    def get_city_id(self, city_name):
        """获取城市ID映射"""
        city_map = {
            '北京': 1,
            '上海': 2,
            # 其他城市映射...
        }
        return city_map.get(city_name, 0)
    
    def generate_signature(self, params):
        """生成接口签名"""
        secret = 'd1d1b1c1a1a1b1c1'  # 需动态获取
        param_str = '&'.join([f'{k}={v}' for k,v in sorted(params.items())])
        return hashlib.md5((param_str + secret).encode()).hexdigest()
    
    def parse_poi_list(self, html):
        """解析店铺列表数据"""
        soup = BeautifulSoup(html, 'lxml')
        shops = []
        for item in soup.select('.poi-list li'):
            shop = {
                'name': item.select_one('.title').text.strip(),
                'score': float(item.select_one('.score').text),
                'reviews': int(item.select_one('.review').text[:-3]),
                'address': item.select_one('.address').text.strip()
            }
            shops.append(shop)
        return shops
    
    def crawl(self, city, max_page=10):
        city_id = self.get_city_id(city)
        result = []
        
        for page in range(1, max_page+1):
            params = {
                'cityId': city_id,
                'page': page,
                'timestamp': int(time.time()*1000)
            }
            params['sign'] = self.generate_signature(params)
            
            try:
                url = f"https://www.meituan.com/meishi/api/poi/getPoiList?{urlencode(params)}"
                resp = requests.get(url, headers=self.headers, proxies=self.proxy)
                data = resp.json()
                
                if data['code'] == 200:
                    result.extend(self.parse_poi_list(data['html']))
                else:
                    print(f"第{page}页抓取失败: {data['msg']}")
                
                time.sleep(1.5)  # 遵守爬虫礼仪
                
            except Exception as e:
                print(f"请求异常: {str(e)}")
                continue
                
        return result

# 使用示例
if __name__ == '__main__':
    spider = MeituanSpider()
    data = spider.crawl('北京', max_page=5)
    print(f"共获取{len(data)}条店铺数据")

四、反反爬策略大全

4.1 IP伪装方案

4.2 请求特征伪装

headers = {
    'Accept-Language': 'zh-CN,zh;q=0.9',
    'Accept-Encoding': 'gzip, deflate, br',
    'Sec-Fetch-Dest': 'document',
    'Upgrade-Insecure-Requests': '1'
}

cookies = {
    '_lxsdk_cuid': '17a...',
    'ci': '1',
    # 其他必要cookies
}

4.3 浏览器自动化方案

from playwright.sync_api import sync_playwright

def browser_crawl(url):
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=False)
        page = browser.new_page()
        page.goto(url)
        
        # 模拟人类操作
        page.mouse.move(100, 100)
        page.wait_for_timeout(500)
        
        html = page.content()
        browser.close()
        return html

五、数据存储与清洗

5.1 MongoDB存储示例

from pymongo import MongoClient

client = MongoClient('mongodb://localhost:27017/')
db = client['meituan']
collection = db['restaurants']

def save_to_mongo(data):
    try:
        result = collection.insert_many(data)
        print(f"插入成功,ID列表: {result.inserted_ids}")
    except Exception as e:
        print(f"存储失败: {str(e)}")

5.2 数据去重方案

def remove_duplicates():
    pipeline = [
        {"$group": {
            "_id": "$name",
            "dups": {"$push": "$_id"},
            "count": {"$sum": 1}
        }},
        {"$match": {"count": {"$gt": 1}}}
    ]
    
    for doc in collection.aggregate(pipeline):
        del doc['dups'][0]
        collection.delete_many({"_id": {"$in": doc['dups']}})

六、法律与道德注意事项

  1. 遵守Robots协议

    • 检查https://www.meituan.com/robots.txt
    • 禁止爬取用户个人信息
  2. 控制请求频率

    • 单IP请求间隔不低于1.5秒
    • 每日抓取量不超过1万条
  3. 数据使用限制

    • 仅用于学术研究或个人学习
    • 禁止商业用途转售

七、性能优化建议

  1. 异步爬虫改造: “`python import aiohttp import asyncio

async def async_crawl(url): async with aiohttp.ClientSession() as session: async with session.get(url) as response: return await response.text()


2. **分布式架构**:
   - 使用Scrapy-Redis搭建分布式爬虫
   - 消息队列采用RabbitMQ/Kafka

3. **断点续爬**:
   ```python
   def save_progress(page):
       with open('progress.txt', 'w') as f:
           f.write(str(page))
           
   def load_progress():
       try:
           with open('progress.txt') as f:
               return int(f.read())
       except:
           return 1

结语

本文详细介绍了爬取美团美食数据的技术方案和实现细节。在实际应用中,建议根据具体需求调整爬取策略,并持续关注美团的反爬机制更新。合规、节制的数据采集才能保证项目的可持续发展。

注意:本文示例代码仅供技术学习参考,请勿用于大规模商业爬取。数据抓取行为应当遵守相关法律法规和网站的使用条款。 “`

这篇文章包含了约3500字的内容,采用Markdown格式编写,包含以下关键要素: 1. 技术背景与挑战分析 2. 完整的技术实现方案 3. 代码示例和参数说明 4. 反爬应对策略 5. 数据存储方案 6. 法律合规建议 7. 性能优化方向

可根据实际需要调整代码细节或补充更多城市的数据映射关系。建议在正式使用前进行小规模测试,确保爬虫的稳定性和合规性。

推荐阅读:
  1. Python爬虫入门【3】:美空网数据爬取
  2. python3怎么实现爬取淘宝美食

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

python

上一篇:怎么用Python做出柱形图

下一篇:用Python怎么做出浪漫又有内涵的图

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》