从豆瓣电影抓取评论:一份完整的 Python 爬虫实现

网络爬虫——python爬取豆瓣评论 网络爬虫,又被称为网络蜘蛛(Web Spider)、网络机器人等。它根据网页地址(URL)爬取网页内容,网页地址(URL)就是我们在浏览器中输入的网站链接。例如:https://www.baidu.com;网络爬虫不仅能够复制网页信息和下载音视频,还可以做到网站的模拟登录和行为链执行。由于需要爬取的网站大多需要先登录才能正常访问,或者需要登录后的cookie值才能继续爬取,所以需要对网站模拟登录。有些网站设置了Referer防盗链,所以需要执行网页浏览行为链。 阅读详情

直接上源码,如果觉得可以点个关注再走。

目录

1. 环境准备

2. 项目结构

3. 核心功能拆解

3.1 配置区(全局常量)

3.2 数据库准备

3.3 Cookie & 登录

3.4 发起 HTTP 请求

3.5 解析与存储

3.6 进度管理

3.7 主流程

3.8 CSV 导出

4. 如何使用

5. 常见问题 & 调试技巧

6. 扩展思路

7. 小结




import os
import time
import random
import json
import sqlite3
import argparse
from bs4 import BeautifulSoup
import requests
import pandas as pd

# Selenium
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager

# ------------- 配置 -------------
BASE_URL = "https://movie.douban.com/subject/26647087/comments"

# 默认为最新评论(可选 'new_score' 或 'time')
SORT_TYPE = "time"

DB_PATH = "douban_comments.db"
COOKIE_SAVE = "cookies_saved.json"

# 每次脚本运行抓取的页数
PAGES_PER_RUN = 5
MAX_TOTAL_PAGES = 5000  # 最大页数(页数 * 20 = 最大起点上限)
SLEEP_BETWEEN_PAGE_MIN = 5
SLEEP_BETWEEN_PAGE_MAX = 10

USER_AGENTS = [
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16 Safari/605.1.15",
]
COOKIE_LIST = []
PROXY_FILE = "proxies.txt"
# --------------------------------


def ensure_db():
    conn = sqlite3.connect(DB_PATH)
    c = conn.cursor()
    # comments 表
    c.execute("""CREATE TABLE IF NOT EXISTS comments
                 (
                     comment_id TEXT PRIMARY KEY,
                     user TEXT,
                     user_url TEXT,
                     rating INTEGER,
                     time TEXT,
                     votes INTEGER,
                     content TEXT
                 )""")
    # progress 表:只保存一行配置(next_start, sort_type)
    c.execute("""CREATE TABLE IF NOT EXISTS progress
                 (
                     id INTEGER PRIMARY KEY AUTOINCREMENT,
                     next_start INTEGER UNIQUE,
                     sort_type TEXT
                 )""")
    # 尝试兼容旧表结构(如果列丢失)
    try:
        c.execute("SELECT sort_type FROM progress LIMIT 1")
    except sqlite3.OperationalError:
        try:
            c.execute("ALTER TABLE progress ADD COLUMN sort_type TEXT")
            print("提示: 已更新数据库结构 (添加 sort_type 字段)")
        except Exception:
            pass

    # 初始化一行进度(如果为空)
    c.execute("SELECT COUNT(*) FROM progress")
    if c.fetchone()[0] == 0:
        c.execute("INSERT INTO progress(next_start, sort_type) VALUES(0, ?)", (SORT_TYPE,))
    conn.commit()
    conn.close()


def load_proxies():
    if not os.path.exists(PROXY_FILE):
        return []
    with open(PROXY_FILE, "r", encoding="utf-8") as f:
        return [l.strip() for l in f if l.strip()]


PROXIES = load_proxies()


def load_saved_cookie():
    if os.path.exists(COOKIE_SAVE):
        try:
            j = json.load(open(COOKIE_SAVE, "r", encoding="utf-8"))
            cookie = j.get("cookie")
            if cookie:
                return cookie
        except Exception:
            pass
    return None


def save_cookie_from_selenium(cookies):
    cookie_str = "; ".join([f"{c['name']}={c['value']}" for c in cookies])
    with open(COOKIE_SAVE, "w", encoding="utf-8") as f:
        json.dump({"cookie": cookie_str, "raw": cookies}, f, ensure_ascii=False, indent=2)
    print("已将 cookie 保存在", COOKIE_SAVE)


def start_selenium(headless=False, user_data_dir=None):
    opts = Options()
    if headless:
        opts.add_argument("--headless=new")
    opts.add_argument("--no-sandbox")
    opts.add_argument("--disable-dev-shm-usage")
    opts.add_argument("--window-size=1200,900")
    if user_data_dir:
        opts.add_argument(f"--user-data-dir={user_data_dir}")

    service = Service(ChromeDriverManager().install())
    driver = webdriver.Chrome(service=service, options=opts)
    return driver


def init_login_manual(profile_dir=None):
    print("打开浏览器,请在弹出窗口里登录豆瓣。登录成功后,请回到这里按回车...")
    driver = start_selenium(headless=False, user_data_dir=profile_dir)
    try:
        driver.get("https://accounts.douban.com/passport/login")
        input("登录完成后,请按回车键继续...")
        cookies = driver.get_cookies()
        save_cookie_from_selenium(cookies)
    finally:
        driver.quit()


def headers_with(cookie_str=None):
    h = {
        "User-Agent": random.choice(USER_AGENTS),
        "Referer": f"{BASE_URL}?status=P",
        "Accept-Language": "zh-CN,zh;q=0.9",
    }
    if cookie_str:
        h["Cookie"] = cookie_str
    return h


def fetch_page_requests(start, cookie_str=None, proxy=None, timeout=15):
    params = {
        "start": start,
        "limit": 20,
        "status": "P",
        "sort": SORT_TYPE
    }

    headers = headers_with(cookie_str)
    proxies_dict = {"http": proxy, "https": proxy} if proxy else None

    proxy_msg = f"[代理: {proxy}]" if proxy else "[直连]"
    print(f"正在抓取: start={start}, sort={SORT_TYPE} {proxy_msg}")

    try:
        resp = requests.get(BASE_URL, params=params, headers=headers, timeout=timeout, proxies=proxies_dict)
        return resp.status_code, resp.text
    except (requests.exceptions.ProxyError, requests.exceptions.ConnectTimeout,
            requests.exceptions.ConnectionError) as e:
        # 如果使用代理失败,尝试直连
        if proxy:
            print(f"  [警告] 代理 {proxy} 连接失败或拒绝,尝试切换本机直连重试...")
            try:
                resp = requests.get(BASE_URL, params=params, headers=headers, timeout=timeout, proxies=None)
                print(f"  [恢复] 本机直连成功。")
                return resp.status_code, resp.text
            except Exception as e2:
                return None, f"直连也失败: {str(e2)}"
        return None, str(e)
    except Exception as e:
        return None, str(e)


def parse_comments(html):
    soup = BeautifulSoup(html, "lxml")
    items = soup.find_all("div", class_="comment-item")
    out = []
    for it in items:
        cid = it.get("data-cid") or it.get("id")
        info = it.find("span", class_="comment-info")
        user, user_url, rating, time_text = None, None, None, None
        if info:
            a = info.find("a")
            if a:
                user = a.get_text(strip=True)
                user_url = a.get("href")
            rs = info.find(
                lambda tag: tag.name == "span" and tag.get("class") and any("allstar" in c for c in tag.get("class")))
            if rs:
                import re
                m = re.search(r"allstar(\d+)", " ".join(rs.get("class")))
                if m:
                    try:
                        rating = int(m.group(1)) // 10
                    except Exception:
                        rating = None
            t = info.find("span", class_="comment-time")
            if t:
                time_text = t.get_text(strip=True)
        content_tag = it.find("p", class_="comment-content")
        if not content_tag:
            content_tag = it.find("span", class_="short")

        content = content_tag.get_text(strip=True) if content_tag else None
        votes_tag = it.find("span", class_="votes")
        votes = 0
        if votes_tag:
            tv = votes_tag.get_text(strip=True)
            if tv.isdigit():
                votes = int(tv)

        if content:
            out.append({
                "comment_id": cid, "user": user, "user_url": user_url, "rating": rating,
                "time": time_text, "votes": votes, "content": content
            })
    return out


def save_comments_to_db(rows):
    if not rows:
        return 0
    conn = sqlite3.connect(DB_PATH)
    c = conn.cursor()
    inserted = 0
    for r in rows:
        try:
            c.execute(
                "INSERT INTO comments(comment_id, user, user_url, rating, time, votes, content) VALUES(?,?,?,?,?,?,?)",
                (r["comment_id"], r["user"], r["user_url"], r["rating"], r["time"], r["votes"], r["content"]))
            inserted += 1
        except sqlite3.IntegrityError:
            # 已存在,跳过
            continue
        except Exception:
            continue
    conn.commit()
    conn.close()
    return inserted


def get_next_start_and_increment():
    """
    更稳健的获取并增加 next_start:
      - 按 id 读取和更新 progress 的行(避免 WHERE next_start 精确匹配失败)
      - 如果检测到 sort_type 变化,会把 next_start 重置为 0 并更新 sort_type
    返回值:当前应抓取的 next_start(未增量)
    """
    conn = sqlite3.connect(DB_PATH)
    c = conn.cursor()

    try:
        c.execute("SELECT id, next_start, sort_type FROM progress ORDER BY id LIMIT 1")
        row = c.fetchone()
    except sqlite3.OperationalError:
        row = None

    if not row:
        # 初始化一行
        c.execute("DELETE FROM progress")
        c.execute("INSERT INTO progress(next_start, sort_type) VALUES(0, ?)", (SORT_TYPE,))
        conn.commit()
        c.execute("SELECT id, next_start, sort_type FROM progress ORDER BY id LIMIT 1")
        row = c.fetchone()

    row_id, next_start, current_db_sort = row[0], row[1], (row[2] if len(row) > 2 else None)

    # 智能重置:如果配置的 sort_type 与 db 中不一致,重置为 0
    if current_db_sort != SORT_TYPE:
        print(f"\n>>> 检测到排序模式变更 ({current_db_sort} -> {SORT_TYPE})")
        print(f">>> 自动将起点从 {next_start} 重置为 0,重新开始抓取...\n")
        next_start = 0
        c.execute("UPDATE progress SET sort_type = ?, next_start = 0 WHERE id = ?", (SORT_TYPE, row_id))
        conn.commit()

    # 计算并保存下一次的起点(按 id 更新)
    new_start = next_start + PAGES_PER_RUN * 20
    c.execute("UPDATE progress SET next_start = ? WHERE id = ?", (new_start, row_id))
    conn.commit()
    conn.close()

    return next_start


def main_run(args):
    ensure_db()
    cookie_saved = load_saved_cookie()
    if cookie_saved:
        COOKIE_LIST.insert(0, cookie_saved)

    if not COOKIE_LIST:
        print("警告: 没有找到保存的 cookie,建议先运行 --init-login")

    proxies = PROXIES

    start = get_next_start_and_increment()
    if start >= MAX_TOTAL_PAGES * 20:
        print("已达到最大设定页数。")
        return

    pages_to_fetch = PAGES_PER_RUN
    print(f"--- 任务开始: 抓取 {pages_to_fetch} 页, 起点 start={start} ---")

    cookie_idx = 0
    proxy_idx = 0
    total_inserted = 0

    page_idx = 0
    # 使用 while 循环以便在需要时调整 start 并在同次运行内继续(当 args.auto_continue=True 时)
    while page_idx < pages_to_fetch:
        cur_start = start + page_idx * 20
        cookie = COOKIE_LIST[cookie_idx % len(COOKIE_LIST)] if COOKIE_LIST else None
        proxy = proxies[proxy_idx % len(proxies)] if proxies else None

        status, html_or_err = fetch_page_requests(cur_start, cookie_str=cookie, proxy=proxy)

        if status == 200:
            parsed = parse_comments(html_or_err)
            if parsed:
                inserted = save_comments_to_db(parsed)
                total_inserted += inserted
                print(f"  [成功] start={cur_start} | 获取: {len(parsed)} 条 | 新入库: {inserted} 条")
            else:
                print(f"  [空数据] start={cur_start} 解析为空。")
                print("    -> 提示: 如果是最新评论也爬完了,说明真的没有更多数据了。")
        elif status == 403:
            print(f"  [403 禁止] start={cur_start} IP或Cookie被封。请暂停一段时间。")
            break
        elif status == 404:
            print(f"  [404 不存在] start={cur_start} 页面不存在 (到达列表末尾)。")

            # 如果本次运行的第一个页(page_idx==0)就是 404,说明 DB 中的 next_start 可能超出了当前可用最大页
            if page_idx == 0:
                print("  -> 检测到首页就是 404,可能起点过高(进度指针超出)。")
                print("     自动将 progress.next_start 重置为 0。")

                try:
                    conn = sqlite3.connect(DB_PATH)
                    c = conn.cursor()
                    c.execute("SELECT id FROM progress ORDER BY id LIMIT 1")
                    row = c.fetchone()
                    if row:
                        row_id = row[0]
                        c.execute("UPDATE progress SET next_start = 0 WHERE id = ?", (row_id,))
                        conn.commit()
                        print("     已将 progress.next_start 置为 0。")
                    conn.close()
                except Exception as e:
                    print("     自动重置进度失败:", e)

                if args.auto_continue:
                    # 在同次运行内从 start=0 继续抓取
                    print("     --auto-continue 已开启:将在本次运行中从 start=0 重新开始抓取。")
                    start = 0
                    cookie_idx = 0
                    proxy_idx = 0
                    page_idx = 0
                    # 注意:不要立即继续下一个循环迭代(本次循环结束后会重新从 page_idx 0 开始)
                    continue
                else:
                    print("     建议稍后再次运行脚本以从头抓取最新评论。")
                    break

            # 如果不是第一个页,那说明后续页已经到尽头,继续或停止由策略决定(这里我们继续循环以尝试下一页)
            else:
                # 直接跳过该页并继续(不会改变 progress,因为我们已经在本次运行中)
                print("    -> 跳过当前页并尝试下一页(如果有)。")
        else:
            print(f"  [错误] start={cur_start} 状态码: {status} | 信息: {html_or_err}")

        # 如果还要继续抓下一页,休眠一小段随机时间
        page_idx += 1
        cookie_idx += 1
        proxy_idx += 1

        if page_idx < pages_to_fetch:
            t = random.uniform(SLEEP_BETWEEN_PAGE_MIN, SLEEP_BETWEEN_PAGE_MAX)
            print(f"    ...等待 {t:.1f} 秒...")
            time.sleep(t)

    print(f"--- 本次任务结束,共新增 {total_inserted} 条记录 ---")

    # 导出到 CSV
    try:
        conn = sqlite3.connect(DB_PATH)
        df = pd.read_sql_query("SELECT * FROM comments", conn)
        df.to_csv("three_body_comments_fixed.csv", index=False, encoding="utf-8-sig")
        conn.close()
        print(f"当前数据库共 {len(df)} 条,已导出至 three_body_comments_fixed.csv")
    except Exception as e:
        print("导出 CSV 失败:", e)


if __name__ == "__main__":
    ap = argparse.ArgumentParser()
    ap.add_argument("--init-login", action="store_true", help="登录并保存cookie")
    ap.add_argument("--profile-dir", type=str, default=None, help="selenium user-data-dir")
    ap.add_argument("--auto-continue", action="store_true", help="当检测到首页 404 并重置进度后,在同次运行里从 start=0 继续抓取")
    args = ap.parse_args()

    if args.init_login:
        init_login_manual(profile_dir=args.profile_dir)
    else:
        main_run(args)

本文基于 Python 3.11+,使用 requests + BeautifulSoup + SQLite + Selenium(可选)完成对单个电影页面下评论的批量抓取。
目标是:

  • 能够在不被豆瓣反爬机制干扰的前提下持续抓取到最新/最高分评论;
  • 自动记录进度,支持断点续跑;
  • 支持代理与 Cookie 切换,以降低 IP/IP 段封禁风险。

1. 环境准备

工具版本安装命令
Python3.11+python -m pip install --upgrade pip
requests, bs4, pandas, selenium, webdriver‑manager依赖pip install requests beautifulsoup4 pandas selenium webdriver-manager

提示:若你在国内访问 Google Chrome 的官方驱动会超时,可改用 webdriver-manager[chromedriver] 或手工下载对应版本的 chromedriver.exe。


2. 项目结构

douban_comment_scraper/
├── proxies.txt          # 可选,代理列表(格式:host:port)
├── cookies_saved.json   # 存储登录后的 Cookie
├── douban_comments.db   # SQLite 数据库
├── three_body_comments_fixed.csv  # 导出的 CSV
└── scraper.py           # 主程序(下文的完整代码)

为什么用 SQLite?

  • 轻量、无需额外服务;
  • 支持事务,防止半路退出导致数据重复或缺失。

3. 核心功能拆解

下面把脚本分块讲解,让你清晰知道每一行代码在做什么。

3.1 配置区(全局常量)

 
BASE_URL = "https://movie.douban.com/subject/26647087/comments"
SORT_TYPE = "time"           # 'new_score' 或 'time'
DB_PATH = "douban_comments.db"
COOKIE_SAVE = "cookies_saved.json"

PAGES_PER_RUN = 5            # 每次脚本运行抓取多少页
MAX_TOTAL_PAGES = 5000       # 最大起点限制(防止无限循环)
SLEEP_BETWEEN_PAGE_MIN = 5   # 随机睡眠,降低被封概率
SLEEP_BETWEEN_PAGE_MAX = 10

USER_AGENTS = [...]          # 常用浏览器 UA 列表
PROXY_FILE = "proxies.txt"

思路:

  • PAGES_PER_RUN 控制一次抓取的粒度,便于后期手动中断。
  • MAX_TOTAL_PAGES 只在极端情况下才触发(比如页面已全部爬完)。

3.2 数据库准备

def ensure_db():
    conn = sqlite3.connect(DB_PATH)
    c = conn.cursor()
    # comments 表
    c.execute("""CREATE TABLE IF NOT EXISTS comments (... )""")
    # progress 表:记录下一页的起点(next_start)和排序方式
    c.execute("""CREATE TABLE IF NOT EXISTS progress (... )""")
    ...

进度表
只保留一行,用来记录 next_start 与当前使用的 sort_type。
当你想改成另一种排序(如从最高分抓起)时,程序会自动重置起点为0。

3.3 Cookie & 登录

 
def init_login_manual(profile_dir=None):
    print("打开浏览器,请在弹出窗口里登录豆瓣。登录成功后,请回到这里按回车...")
    driver = start_selenium(headless=False, user_data_dir=profile_dir)
    ...

  • 通过 Selenium 打开一个真实的 Chrome 实例,让你手动完成登录。
  • 登录成功后,脚本会把 Cookie 保存为 cookies_saved.json,之后所有请求都带上该 Cookie。

为什么要用 Selenium?

  • 豆瓣对无 Cookie 的请求会直接跳转到登录页;
  • 通过 Selenium 可以完整模拟人类操作,获取 sessionid 等隐藏字段。

3.4 发起 HTTP 请求

 
def fetch_page_requests(start, cookie_str=None, proxy=None, timeout=15):
    params = {"start": start, "limit": 20, ...}
    headers = headers_with(cookie_str)
    proxies_dict = {"http": proxy, "https": proxy} if proxy else None
    ...

  • start 表示评论列表的偏移量(每页 20 条)。
  • 代理失败时,自动回退到直连;若直连也失败,则返回错误信息。

3.5 解析与存储

 
def get_next_start_and_increment():
    ...

  • 用 BeautifulSoup 提取:评论 ID、用户昵称、评分、时间、投票数、正文。
  • 结果列表随后通过 save_comments_to_db() 写入 SQLite。

去重
comment_id 是主键,SQLite 的 INSERT OR IGNORE 可以避免重复插入。

3.6 进度管理

 

def get_next_start_and_increment(): ...

  • 从 progress 表读取当前 next_start。
  • 若数据库中的 sort_type 与脚本配置不一致,自动将起点重置为0并更新 sort_type。
  • 计算下一次的起点:next_start + PAGES_PER_RUN * 20 并写回。

好处

  • 支持断点续跑;
  • 防止因为手动更改 SORT_TYPE 而导致抓取错误。

3.7 主流程

def main_run(args):
    ensure_db()
    cookie_saved = load_saved_cookie()
    ...
    start = get_next_start_and_increment()
    ...
  • 每次运行会根据 PAGES_PER_RUN 抓取若干页。
  • 支持多 Cookie 与多代理轮流使用(提高成功率)。
  • 处理各种 HTTP 状态码:200、403、404 等。
  • 在每页结束后随机休眠,模拟人类行为。

auto-continue
如果第一次请求返回 404(说明起点已超出实际页面),程序会把进度重置为0,并在同一次运行中继续抓取。这对于“从头开始”非常方便。

3.8 CSV 导出

conn = sqlite3.connect(DB_PATH)
df = pd.read_sql_query("SELECT * FROM comments", conn)
df.to_csv("three_body_comments_fixed.csv", index=False, encoding="utf-8-sig")
  • 每次运行结束后,自动把数据库里的所有评论导出为 CSV。
  • 方便后期分析(如情感倾向、评分分布等)。

4. 如何使用

  1. 克隆或下载代码

    git clone https://github.com/yourname/douban_comment_scraper.git
    cd douban_comment_scraper
    

  2. 准备代理(可选)

    • 在 proxies.txt 中每行写一个代理,例如:
      127.0.0.1:10809
      114.114.114.114:80

    • 如果不需要代理,直接删掉文件或留空。
  3. 登录并保存 Cookie

    python scraper.py --init-login
    
    • 浏览器会弹出,按提示完成豆瓣账号登录。
    • 登录成功后回到终端按回车即可完成 Cookie 保存。
  4. 开始抓取

     
    python scraper.py          # 默认每次抓 5 页
    python scraper.py --auto-continue  # 自动重置起点并继续抓取
    

  5. 查看结果

    • douban_comments.db:SQLite 数据库,直接用 DB Browser for SQLite 打开即可。
    • three_body_comments_fixed.csv:完整 CSV 文件,可导入 Excel、Pandas 等工具分析。

5. 常见问题 & 调试技巧

场景解决方案
403 Forbidden可能 Cookie 被封,或 IP 被限流。<br>尝试切换代理或重新登录获取新 Cookie。
404 Not Found起点超出了实际页面数量。<br>使用 --auto-continue 或手动将 next_start 重置为0(直接编辑 DB)。
请求被重定向到 login 页面检查 Cookie 是否正确,或尝试手动登录后再次抓取。
解析不到评论可能页面结构变更;检查 parse_comments() 中的选择器是否仍有效。

调试建议

  • 在 fetch_page_requests 中打印完整响应文本 (resp.text[:500]) 可快速定位是否被重定向。
  • 使用 sqlite3 的事务模式(默认)可以避免数据不一致。

6. 扩展思路

  1. 多电影批量抓取
    把 BASE_URL 换成循环列表,或从一个 CSV 中读取电影 ID。

  2. 分布式部署
    将 SQLite 换成 PostgreSQL 或 MySQL,然后用 Celery 分配任务。

  3. 数据清洗 & NLP
    用 jieba, snownlp 对评论文本做分词、情感分析,生成可视化报告。

  4. 监控与告警
    每次抓取完毕后发送邮件或推送到 Slack 以提醒任务完成。


7. 小结

这份脚本把豆瓣评论的爬取拆解成了请求、解析、存储、进度管理四大模块,并通过 Cookie + 代理轮转 与 随机睡眠 等手段降低被封风险。
如果你想抓取自己的电影或其他站点的评论,只需改动 BASE_URL、适配 HTML 结构即可。

希望这篇博客能帮助你快速上手并扩展自己的数据采集项目!

Python 爬虫之爬豆瓣TOP250电影 爬虫超详细讲解 零基础入门 先看后赞,养成习惯!!! 点赞收藏,人生辉煌!!! 讲解我们的爬虫之前,先概述关于爬虫的简单概念(毕竟是零基础教程) 爬虫 网络爬虫(又被称为网页蜘蛛,网络机器人)就是模拟浏览器发送网络请求,接收请求响应,一种按照一定的规则,自动地抓取互联网信息的程序。 原则上,只要是浏览器(客户端)能做的事情,爬虫都能够做。 为什么我们要使用爬虫 互联网大数据时代,给予我们的是生活的便利以及海量数据爆炸式的出现在网络中。 过去,我们通过书籍、报纸、电视、广播或许信息,这些信息数量有限,且... 阅读详情

相关推荐

Python爬虫项目集:豆瓣电影排行榜top250

爬虫写得好,牢饭吃到饱”,业内常用这个段子来调侃爬虫工程师。因为做爬虫有些敏感、重要的数据是不能随便抓取,进行商业利用的,不然随时都可能被请去“喝茶”。今年,就有好多互金公司因为爬虫的问题,被举报调查。但不管怎样,爬虫技术是无罪的,还是值得我们开发人员去学习了解一下的。在学习之前,我们还是要先了解一下相关概念。网络爬虫:又被称为网页蜘蛛,网络机器人,是一种按照一定的规则,自动的抓取万维网信息的程序或者脚本。

2401_85900557的博客 1943

Python爬虫爬取豆瓣电影短评(爬虫入门,Scrapy框架,Xpath解析网站,jieba分词)

很久之前就想学爬虫了,但是一直没机会,这次终于有机会了 主要参考了《疯狂python讲义》的最后一章

crosnken的博客 3415

Python爬虫1-利用Scrapy抓取豆瓣电影top250数据

Python爬虫-利用Scrapy抓取豆瓣电影top250数据 简介 一段自动抓取互联网信息的程序 Python爬虫架构: 调度端:用来启动、停止、和监视爬虫 URL管理:对等待爬取和已经爬取的URL进行管理,简单来说就是为后续模块提供可供爬取的URL 网页下载器:将供爬取的URL的网页下载下来,组成供解析的字符串 网页解析器:将字符串解析 scrapy抓取步骤 新建项目 (...

liuwei_q的博客 5015

用python爬取豆瓣评分数据(附完整源码)爬豆瓣电影上指定电影的短评(保姆级别教学)

1、在navict中新建一个数据库,在数据库下面新建一个表并命名,红色标注的地方填你自己在数据标注命名的名字。二、打开pycharm , 把我给大家的代码复制粘贴,然后修改以下几个地方就ok了。结束啦,以上准备工作做完之后,就可以运行咱们的代码去爬取自己想要的数据了~4、点击第一个文件,就可以找到我们代码中所需要的地址代码。1、把上面我们在网站上找到的相关代码打上去。一、找到你想要爬取的网站数据代码(步骤如下)2、红色标注的地方是你想爬取的网站地址。1、打开你想要爬取的网站,点击“设置”

2301_79629586的博客 5189

编写Python爬虫抓取豆瓣电影TOP100及用户头像的方法

这篇文章主要介绍了编写Python爬虫抓取豆瓣电影TOP100及用户头像的方法,用到了Python的urllib和urllib2模块,需要的朋友可以参考下 抓取豆瓣电影TOP100 一、分析豆瓣top页面,构建程序结构 1.首先打开网页http://movie.douban.com/top250?start,也就是top页面 然后试着点击到top100的页面,注意带top100的链接依次为 htt...

python入门教程 4278

五分钟学会Python网络爬虫

但不管怎样,爬虫技术是无罪的,还是值得我们开发人员去学习了解一下的。在学习之前,我们还是要先了解一下相关概念。 什么是爬虫 网络爬虫:又被称为网页蜘蛛,网络机器人,是一种按照一定的规则,自动的抓取万维网信息的程序或者脚本。 大数据时代,要进行数据分析,首先要有数据源,可数据源从哪里来,花钱买,没预算,只能从其它网站就行抓取。 细分下来,业内分为两类:爬虫和反爬虫。 反爬虫:顾名思义,就是防止你来我网站或APP上做爬虫的。 爬虫工程师和反爬虫工程师是一对相爱相杀的小伙伴,经常因为对方要加班写代码,

python588的博客 2363

【爬虫实战】用python爬豆瓣电影《热烈》的短评!

马哥原创:用python爬豆瓣电影短评,字段含:评论者昵称, 评论星级, 评论时间, 评论者IP属地, 有用数, 评论内容。

马哥的专栏 3986

【Python学习】网络爬虫-爬取豆瓣电影评论

【Python学习】网络爬虫-爬取豆瓣电影评论:本实例实现了庆余年的豆瓣电影评论爬取,使用了requests、bs4模块。requests:是一个常用的 HTTP 请求库,可以方便地向网站发送 HTTP 请求,并获取响应结果。requests 模块比urllib模块更简洁。bs4:全名,是编写 python 爬虫常用库之一,主要用来解析 html 标签。

u014481728的博客 1万+

Python入门- 复仇者联盟4短评(Day10)

今天来学习下如何获取文章短评,话不多说,直接上代码。

xiaoshun007的专栏 237

Python 网络爬虫实战:如何高效爬取豆瓣电影评论并提取有价值数据

本文介绍了如何利用Python爬取豆瓣电影评论并进行文本分析。通过requests和BeautifulSoup获取静态评论数据,或用Selenium处理动态加载,再借助Pandas清洗数据。使用TF-IDF提取关键词,结合TextBlob进行情感分析,最终根据情感倾向生成吸引人的标题(如"为何这部电影受欢迎?")。该方法可高效分析用户评论,为内容创作和市场研究提供参考,未来还可结合深度学习模型优化标题生成。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 1777

豆瓣电影数据抓取Python爬虫详解

网络爬虫(Web Crawler),又称网络蜘蛛(Web Spider),是一种自动获取网页内容的程序,它可以按照一定的规则,自动浏览互联网中的网页,抓取所需数据。Python因其简单易学和强大的库支持,成为开发爬虫的首选语言。反爬虫机制是爬虫工程师必须面对的挑战之一。通过识别和分析常见的反爬虫技术,爬虫工程师可以设计出更为复杂和高效的爬虫策略。模拟登录、管理Cookies以及使用Selenium等工具动态加载JavaScript内容都是有效的应对措施。

weixin_42613017的博客 1299

python爬取豆瓣短评_爬虫-爬取豆瓣短评

爬虫-爬取豆瓣短评啥是爬虫?​按照一定的规则,自动地抓取互联网信息的程序。为啥要用爬虫?​可以利用爬虫自动地采集互联网中的信息,采集回来后进行相应的存储或处理,在需要检索某些信息的时候,只需在采集回来的信息中进行检索怎么用爬虫?爬虫分为三个部分1、解析网页2、提取信息3、保存信息接下来将会用requests库来实现一个简单地爬虫爬取豆瓣短评首先我们需要安装requests库我们可以cmd指令进入p...

weixin_39758953的博客 1128

新手必看!Unity中Tag和Layer的7个实际应用场景(含MOBA案例)

本文深入探讨Unity中Tag和Layer的7个实际应用场景,特别以MOBA游戏开发为例,详细解析如何利用LayerMask进行高效场景管理和碰撞检测优化。从双相机方案到射线检测的精准控制,帮助开发者掌握这些基础功能的进阶用法,提升游戏性能和开发效率。

weixin_28723171的博客 313

Python爬虫之豆瓣电影评论数据的爬取(十四)

爬取豆瓣网上面的电影评论数据具有很重要的作用。电影评论数据是NLP(自然语言处理)重要的数据。通过电影评论数据集可以进一步做中文分词、命名实体识别、关键词提取、句法分析、文本向量化、情感分析、舆情分析等进一步的数据处理和应用。既然数据这么重要,废话不多说,紧接着就开始电影数据的爬取。

Blessy_Zhu的博客 3万+

UVM环境复位--stop_sequences()

在UVM验证环境中, stop_sequences是一个用于强制终止所有正在运行的 Sequence 的方法,通常用于动态控制激励生成流程。1.通过uvm_config_db传递事件和严格的同步机制,此方案符适用于复杂复位场景和动态测试控制。组件耦合:Driver 和 Sequence 不再直接依赖env,通过标准接口通信。竞争条件:确保 Driver 完成清理后再终止 Sequence。代码健壮性:使用非阻塞操作和事件监听,避免死锁。

qq_42779035的博客 3016

拆开华为BBU5900,看看5G基站的大脑里到底装了啥?

本文深度拆解华为BBU5900,揭示5G基站核心处理单元的硬件架构与设计哲学。通过详细解析模块化设计、智能电源系统和动态散热方案,展现其支撑千兆速率、毫秒级时延的技术奥秘,为5G网络部署提供实用参考。

weixin_31456563的博客 565

使用网络爬虫爬取豆瓣电影网站的数据

👨‍💻。

php优质创造者 3102

OCR开发实战:如何用PaddleOCR C++版实现本地文字识别(附模型文件处理技巧)

本文详细介绍了如何使用PaddleOCR C++版实现本地文字识别,包括环境搭建、工程编译、运行时优化等全流程。重点讲解了在VS2019/VS2022环境下配置PaddleOCR的CPU推理性能优化技巧,以及模型文件处理的实际应用方法,帮助开发者高效完成OCR本地化部署。

devops8pract的博客 335

Python与网络爬虫案例:电影评论抓取

让我们一起探索新奇的事物,分享生活的点滴,让这个小角落成为我们共同的精神家园。这里不仅有好玩的内容和知识等着你,还特别欢迎你畅所欲言,分享你的想法和见解。你可以把这里当作自己的家,无论是工作之余的小憩,还是寻找灵感的驿站,我都希望你能在这里找到属于你的那份快乐和满足。正所谓“工欲善其事,必先利其器”,在开始我们的爬虫之旅前,我们需要准备好必要的工具和环境。数据清洗的主要目的是去除无效或错误的数据,保证后续分析的准确性。

master_chenchen的博客 910

如何通过Davinci Configurator来新增一个BswM仲裁规则

详细介绍如何通过Davinci Configurator来新增一个BswM仲裁规则。

initiallizer的博客 773

【肌电处理】肌电信号EMG积分肌电值+均方根值+中值频率+平均功率频率【含Matlab源码 3386期】

肌电信号EMG积分肌电值+均方根值+中值频率+平均功率频率 完整的代码,方可运行;可提供运行操作视频!适合小白!

订阅付费专栏Matlab(奶茶价版),可赠送奶茶价版付费专栏指定代码1份; 826

Python实现输入电影名字自动生成豆瓣评论词云图(带GUI界面)小程序

一、项目背景 电影逐渐成为人们生活的不可或缺的一部分,而了解一部电影的可以通过电影评分与大众推荐度,但以上的方式都太过于片面,了解一部电影的方法是通过已经观看完电影的人群的反馈,虽然电影评分和大众推荐度在一定程度上是观影人群的反馈,但是并没有电影评论的反馈真实。评论对影视剧的好坏与特色可以更加充分的体现。所以了解一部影视作品的最好方式是通过评论。出于对评论的大量且参差不齐的考虑,通过出现的高频词来分析,是通过评论了解影视剧较为便捷的方式。将高频词整合,通过词云图是极好的方式。所以项目基于以上背景决定基于网络

Q_U_A_R_T_E_R的博客 6666

静态编译Qt5源码(Kylin-Desktop-V10-SP1-2203-LoongArch64+qt5.15.16)

之前的文档,记录的是通用情况,本次笔者记录下Qt5的静态编译过程,供有需要的小伙伴参考使用的操作系统是Kylin-Desktop-V10-SP1-General-Release-2203-LoongArch64,处理器是龙芯3A5000,架构是loongarch。

aggs1990的专栏 1403

Python网络爬虫实战:爬取豆瓣电影评论数据

网络爬虫是自动化获取网页数据的核心技术,广泛应用于数据分析、市场调研等领域。本文以豆瓣电影《封神第二部:战火西岐》的短评数据为例,展示如何通过Python的。:若页面数据通过JavaScript加载,可使用。:用户名、赞同数、评论时间、IP地址、评论内容。通过本文,你可以快速掌握基础爬虫的实现逻辑。库实现评论数据的爬取,并整理为结构化数据。:豆瓣电影《封神第二部:战火西岐》短评页面。BeautifulSoup官方文档。控制爬取速度,减少服务器压力。:通过分析分页URL规律(如。规则,避免爬取敏感信息。

Lmx070411的博客 1719

YOLOv11改进策略【Head/分割头】| 结合CVPR-2024 中的DynamicConv 动态卷积 改进分割头, 优化模型(独家改进)

在大规模视觉预训练中,通常模型的性能受到数据、参数和FLOP三个关键因素的影响。一般来说,模型的参数数量越多,FLOP也越高,但在移动设备等对计算资源有限制的场景下,需要低FLOP的模型同时又希望模型能从大规模预训练中受益。传统的方法很难在增加参数的同时保持低FLOP,因此需要一种新的设计来解决这个问题,模块应运而生。

Limiiiing的博客 2318

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Python爬虫实战:爬取豆瓣电影

网络爬虫是一种自动化程序,能够从互联网上抓取数据。它通过模拟浏览器请求,访问网页并提取所需的信息。发送HTTP请求:向目标网站发送请求,获取网页内容。解析HTML:从网页中提取有用的数据。存储数据:将提取的数据保存到本地或数据库中。本文通过一个简单的豆瓣电影Top250爬虫实例,介绍了Python爬虫的基本流程。我们从发送HTTP请求、解析HTML到存储数据,逐步实现了一个完整的爬虫程序。此外,我们还探讨了如何处理分页和动态内容,以及应对常见的反爬虫策略。

weixin_45145684的博客 2400

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

上一篇: 【图神经网络:原理与实战】第十三章13.1 推荐系统:动态图与自监督实践
下一篇: 腾讯视频评论抓取脚本详细使用教程
VectorShift
博客等级 码龄1年 1840粉丝 1109原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

VectorShift

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值