无法使用CSS选择器在python中获取数据

问题描述

嗨,我想从这个website中获得电影标题:

enter image description here

url = "https://www.the-numbers.com/market/" + "2019" + "/top-grossing-movies"
raw = requests.get(url,headers={'User-Agent':'Mozilla/5.0'})  
html = BeautifulSoup(raw.text,"html.parser")
movie_list = html.select("#page_filling_chart > table > tbody > tr > td > b > a")
for i in range(len(movie_list)):
    print(movie_list[i].text)

我得到了200的响应,并且没有其他爬网信息的问题。但问题出在movie_list变量中。

当我打印(movie_list)时,它只返回一个空列表,这意味着我使用的标签错误。

解决方法

如果您替换:

movie_list = html.select("#page_filling_chart > table > tbody > tr > td > b > a")

使用:

movie_list = html.select("#page_filling_chart table tr > td > b > a")

您得到了我想找的东西。此处的主要更改是用子代选择器(parent > child)替换子选择器(ancestor descendant),这对于中间内容的外观要宽容得多。


更新:这很有趣。您选择的BeautifulSoup解析器似乎会导致不同的行为。

比较:

>>> html = BeautifulSoup(raw,'html.parser')
>>> html.select('#page_filling_chart > table')
[]

使用:

>>> html = BeautifulSoup(raw,'lxml')
>>> html.select('#page_filling_chart > table')
[<table>
<tr><th>Rank</th><th>Movie</th><th>Release<br/>Date</th><th>Distributor</th><th>Genre</th><th>2019 Gross</th><th>Tickets Sold</th></tr>
<tr>
[...]

实际上,使用lxml解析器,您可以几乎使用原始选择器。这有效:

html.select("#page_filling_chart > table > tr > td > b > a"

解析后,table没有tbody

经过一番尝试后,您必须像这样重写原始查询,才能使其与html.parser一起使用:

html.select("#page_filling_chart2 > p > p > p > p > p > table > tr > td > b > a")

在源中缺少html.parser元素时,似乎</p>不会合成关闭的元素,因此所有未关闭的<p>标签都会导致文档结构解析异常。

,

这是此问题的解决方案:

from bs4 import BeautifulSoup
import requests

url = "https://www.the-numbers.com/market/" + "2019" + "/top-grossing-movies"
raw = requests.get(url,headers={'User-Agent':'Mozilla/5.0'})  
html = BeautifulSoup(raw.text,"html.parser")
movie_table_rows = html.findAll("table")[0].findAll('tr')

movie_list = []
for tr in movie_table_rows[1:]:
    tds = tr.findAll('td')
    movie_list.append(tds[1].text) #Extract Movie Names

print(movie_list)

基本上,您尝试提取文本的方式不正确,因为每个电影名称锚标记的选择器都不同。

,

这应该有效:

url = 'https://www.the-numbers.com/market/2019/top-grossing-movies'
raw = requests.get(url)  
html = BeautifulSoup(raw.text,"html.parser")
movie_list = html.select("table > tr > td > b > a")
for i in range(len(movie_list)):
    print(movie_list[i].text)

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...