Python新手请教:为什么用BeautifulSoup爬虫爬不到目标数据?

买了本书从零开始初步摸门,虽然已经把书看了一轮了,现在才开始了动手的, 书后面是有提到 xml,lxml 的各种方式(也许高手们都倾向这些方式), 但我还是打算先搞通 html.parser 这个初步方式,获取小目标的成功。。。

随便在网上找了个表格网页,获取其中一个产品的规格。。。

用的是 firefox 56.0,自带开发者工具。 右键目标元素,在 firefox 查看器里右键,复制,Xpath,

得到的是: /html/body/table[2]/tbody/tr[2]/td[2]/table/tbody/tr[3]/td/table/tbody/tr[1]/td[2]/table[2]/tbody/tr[11]/td[3]

我看书上写的目标元素路径是用 > 表示的(书上提到他的浏览器是 chrome )

尝试用两种表示方式,都 print 不出目标

是 soup.select()路径的问题?

#coding=UTF-8
import requests
from bs4 import BeautifulSoup

headers = { ‘User-Agent’:‘Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36’ } url = ‘http://www.chinatimber.org/bj/

page_req = requests.get(url,headers=headers) soup = BeautifulSoup(page_req.text,‘html.parser’)

print(soup.select(‘html > body > table[2] > tbody > tr[2] > td[2] > table > tbody > tr[3] > td > table > tbody > tr[1] > td[2] > table[2] > tbody > tr[1] > td[3]’)) print(soup.select(’/html/body/table[2]/tbody/tr[2]/td[2]/table/tbody/tr[3]/td/table/tbody/tr[1]/td[2]/table[2]/tbody/tr[1]/td[3]’))


Python新手请教:为什么用BeautifulSoup爬虫爬不到目标数据?

10 回复

pd.read_html(page_req)[0]


问题分析:
你爬不到数据,大概率是这几个原因:1)网页是动态加载的(JS渲染),BeautifulSoup只能解析静态HTML;2)目标数据在iframe或特殊标签里;3)请求头被网站屏蔽;4)选择器写错了。

解决方案:

  1. 先检查网页源码:右键“查看网页源代码”,搜一下你要的数据在不在里面。如果不在,那就是动态加载,得用Selenium或requests-html这类工具。
  2. 如果是静态页面但爬不到,试试下面这段代码,重点看注释里的排查点:
import requests
from bs4 import BeautifulSoup

url = "你的目标网址"
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}
try:
    resp = requests.get(url, headers=headers, timeout=5)
    resp.raise_for_status()  # 检查请求是否成功
    soup = BeautifulSoup(resp.text, 'html.parser')
    
    # 排查点1:确认编码
    print("页面编码:", resp.encoding)
    
    # 排查点2:先打印一段原始HTML,看数据是否在响应里
    print(soup.prettify()[:2000])
    
    # 排查点3:用简单标签测试选择器是否有效
    test = soup.find('title')
    print("页面标题:", test)
    
    # 排查点4:如果数据在表格或特定class里,检查标签结构
    # 示例:提取所有class为'target'的div
    target_data = soup.find_all('div', class_='target')
    print("找到的目标数据数量:", len(target_data))
    
except requests.exceptions.RequestException as e:
    print("请求失败:", e)
except Exception as e:
    print("解析出错:", e)
  1. 如果数据在JS动态加载,改用Selenium:
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
driver.get(url)
# 等待数据加载(根据实际情况调整等待方式)
driver.implicitly_wait(3)
data = driver.find_element(By.CLASS_NAME, 'target-class').text
print(data)
driver.quit()

一句话总结:先看源码确认数据来源,静态页面检查选择器和请求头,动态页面换Selenium。

删去 tbody 试试

浏览器会自动加 tbody
但是有些没 tbody 的,lxml 也取不到数据,我很郁闷,也不知道为啥,反正不是正经事儿,就算了

1.你应该 copy selector,而不是 xpath
2.这样 print 只会得到一个 object 吧?后面要加 content 或者 text()什么的
我也没怎么用 bs,你再查查 bs 手册

我觉得你还是要学一学 css selector 或者 xpath 语法,这个应该先行
速成可以搜搜 css xpath cheatsheet

有些 id 或 class 是整个页面唯一的,那么你直接 select 这个标志会快一点

虽然右键获取是一个捷径,但是有时候会选择的不出来。
还是认真学一下 css 选择器。不过 BeautifulSoup 里面的 find()和 find_all()更加好理解。

不要用 html parse,我碰到过问题,换成 html5lib 就好了

BeautifulSoup 不支持 xpath,soup.select 得用 css selector。

我都无差别 lxml 的。。。有啥区别吗

回到顶部