ts
This commit is contained in:
+33
-53
@@ -2,15 +2,13 @@
|
|||||||
# 核心功能:
|
# 核心功能:
|
||||||
# - login_mode_auto(): 打开浏览器手动登录,检测到已登录后自动保存 storage_state.json
|
# - login_mode_auto(): 打开浏览器手动登录,检测到已登录后自动保存 storage_state.json
|
||||||
# - check_login_state_with_storage(): 用 storage_state.json 检查登录是否有效
|
# - check_login_state_with_storage(): 用 storage_state.json 检查登录是否有效
|
||||||
# - resolve_profile_by_search(): 通过“搜索页-用户”解析出个人主页 url + 昵称 + 小红书号(需要登录态)
|
# - resolve_profile_by_search(): 通过"搜索页-用户"解析出个人主页 url + 昵称 + 小红书号(需要登录态)
|
||||||
# - crawl_detail(): 详情弹框采集(标题/时间地点/赞藏评),防漏采滚动策略(需要登录态)
|
# - crawl_detail(): 详情弹框采集(标题/时间地点/赞藏评),防漏采滚动策略(需要登录态)
|
||||||
|
|
||||||
import re
|
import re
|
||||||
import json
|
import json
|
||||||
import random
|
import random
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import shutil
|
import shutil
|
||||||
|
|
||||||
# Excel 导出(可选)
|
# Excel 导出(可选)
|
||||||
@@ -74,36 +72,9 @@ USER_DESC_SELECTOR = ".user-desc"
|
|||||||
# 未登录/拦截时常见文本(兜底判断)
|
# 未登录/拦截时常见文本(兜底判断)
|
||||||
BLOCK_TEXTS_STRONG = ["扫码登录", "安全验证", "请先登录", "登录后查看"]
|
BLOCK_TEXTS_STRONG = ["扫码登录", "安全验证", "请先登录", "登录后查看"]
|
||||||
|
|
||||||
def _winreg_app_path(exe_name: str) -> str:
|
|
||||||
"""Windows: 从注册表 App Paths 获取浏览器路径(支持非 C 盘安装)"""
|
|
||||||
if sys.platform != "win32":
|
|
||||||
return ""
|
|
||||||
try:
|
|
||||||
import winreg
|
|
||||||
except Exception:
|
|
||||||
return ""
|
|
||||||
subkey = fr"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\{exe_name}"
|
|
||||||
for root in (getattr(winreg, "HKEY_CURRENT_USER", None), getattr(winreg, "HKEY_LOCAL_MACHINE", None)):
|
|
||||||
if root is None:
|
|
||||||
continue
|
|
||||||
try:
|
|
||||||
k = winreg.OpenKey(root, subkey)
|
|
||||||
try:
|
|
||||||
val, _ = winreg.QueryValueEx(k, "")
|
|
||||||
val = (val or "").strip()
|
|
||||||
if val and Path(val).exists():
|
|
||||||
return val
|
|
||||||
finally:
|
|
||||||
try:
|
|
||||||
winreg.CloseKey(k)
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
return ""
|
|
||||||
|
|
||||||
|
|
||||||
def _which(cmd: str) -> str:
|
def _which(cmd: str) -> str:
|
||||||
|
"""在 Linux 系统上查找命令路径"""
|
||||||
try:
|
try:
|
||||||
return shutil.which(cmd) or ""
|
return shutil.which(cmd) or ""
|
||||||
except Exception:
|
except Exception:
|
||||||
@@ -111,32 +82,41 @@ def _which(cmd: str) -> str:
|
|||||||
|
|
||||||
|
|
||||||
def find_system_browser_executable() -> str:
|
def find_system_browser_executable() -> str:
|
||||||
"""自动探测系统 Chrome/Edge 可执行文件路径"""
|
"""
|
||||||
chrome = _winreg_app_path("chrome.exe")
|
自动探测系统 Chrome/Chromium 可执行文件路径(Linux)
|
||||||
if chrome:
|
常见安装路径:
|
||||||
return chrome
|
- google-chrome: /usr/bin/google-chrome
|
||||||
edge = _winreg_app_path("msedge.exe")
|
- chromium: /usr/bin/chromium-browser
|
||||||
if edge:
|
- chromium: /usr/bin/chromium
|
||||||
return edge
|
"""
|
||||||
|
# Linux 常见的 Chrome/Chromium 命令
|
||||||
candidates = [
|
commands = [
|
||||||
r"C:\Program Files\Google\Chrome\Application\chrome.exe",
|
"google-chrome",
|
||||||
r"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe",
|
"google-chrome-stable",
|
||||||
os.path.expandvars(r"%LOCALAPPDATA%\Google\Chrome\Application\chrome.exe"),
|
"chromium-browser",
|
||||||
r"C:\Program Files\Microsoft\Edge\Application\msedge.exe",
|
"chromium",
|
||||||
r"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe",
|
"chrome",
|
||||||
os.path.expandvars(r"%LOCALAPPDATA%\Microsoft\Edge\Application\msedge.exe"),
|
|
||||||
]
|
]
|
||||||
for p in candidates:
|
|
||||||
|
for cmd in commands:
|
||||||
|
p = _which(cmd)
|
||||||
|
if p:
|
||||||
try:
|
try:
|
||||||
if p and Path(p).exists():
|
if Path(p).exists():
|
||||||
return p
|
return p
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
for cmd in ("chrome", "chrome.exe", "msedge", "msedge.exe"):
|
# 常见路径(如果不在 PATH 中)
|
||||||
p = _which(cmd)
|
candidates = [
|
||||||
if p:
|
"/usr/bin/google-chrome",
|
||||||
|
"/usr/bin/google-chrome-stable",
|
||||||
|
"/usr/bin/chromium-browser",
|
||||||
|
"/usr/bin/chromium",
|
||||||
|
"/opt/google/chrome/google-chrome",
|
||||||
|
"/snap/bin/chromium",
|
||||||
|
]
|
||||||
|
for p in candidates:
|
||||||
try:
|
try:
|
||||||
if Path(p).exists():
|
if Path(p).exists():
|
||||||
return p
|
return p
|
||||||
@@ -147,7 +127,7 @@ def find_system_browser_executable() -> str:
|
|||||||
|
|
||||||
|
|
||||||
def pick_browser_executable(manual_path: str = "") -> str:
|
def pick_browser_executable(manual_path: str = "") -> str:
|
||||||
"""优先使用手动路径;否则自动探测系统 Chrome/Edge;都没有则返回空字符串"""
|
"""优先使用手动路径;否则自动探测系统 Chrome/Chromium;都没有则返回空字符串"""
|
||||||
mp = (manual_path or "").strip().strip('"')
|
mp = (manual_path or "").strip().strip('"')
|
||||||
if mp:
|
if mp:
|
||||||
try:
|
try:
|
||||||
@@ -1008,7 +988,7 @@ def crawl_detail(
|
|||||||
storage_state=str(pth),
|
storage_state=str(pth),
|
||||||
viewport={"width": 1366, "height": 820},
|
viewport={"width": 1366, "height": 820},
|
||||||
locale="zh-CN",
|
locale="zh-CN",
|
||||||
user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36",
|
user_agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36",
|
||||||
)
|
)
|
||||||
context.set_default_timeout(60000)
|
context.set_default_timeout(60000)
|
||||||
page = context.new_page()
|
page = context.new_page()
|
||||||
|
|||||||
Reference in New Issue
Block a user