无法使用 css 选择器获取 python 中的数据
Can't use a css selector to get data in python
嗨,我想从中获取电影片名website:
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)时,它returns只是一个空列表,这意味着我使用了错误的标签。
下面是这个问题的解答:
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)
基本上,您尝试提取文本的方式不正确,因为每个电影名称锚标记的选择器都不同。
如果你替换:
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")
你得到了我认为你正在寻找的东西。此处的主要更改是用后代选择器 (ancestor descendant
) 替换 child-selectors (parent > child
),这对于中间内容的外观而言更加宽容。
更新:这很有趣。您选择的 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>
标签导致一个奇怪的解析文档结构。
这应该有效:
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)
嗨,我想从中获取电影片名website:
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)时,它returns只是一个空列表,这意味着我使用了错误的标签。
下面是这个问题的解答:
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)
基本上,您尝试提取文本的方式不正确,因为每个电影名称锚标记的选择器都不同。
如果你替换:
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")
你得到了我认为你正在寻找的东西。此处的主要更改是用后代选择器 (ancestor descendant
) 替换 child-selectors (parent > child
),这对于中间内容的外观而言更加宽容。
更新:这很有趣。您选择的 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>
标签导致一个奇怪的解析文档结构。
这应该有效:
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)