美女汤 如何从伪元素类中获取href链接?

问题描述 投票:1回答:1

我正试图解析 https:/www.tandfonline.comtocicbi20current 为所有文章的标题。该 HTML 分为卷和期。每一卷有一个问题,对应一个月。所以第36卷有12期。在当前的卷(37)中,有4个问题,我想解析每个问题,并得到每个文章的名字。

enter image description here

为了达到这个目的,并自动搜索,我需要取得 href 每期的链接。最初我选择了父母的 div id: id = 'tocList'.

import requests
from bs4 import BeautifulSoup, SoupStrainer

chronobiology = requests.get("https://www.tandfonline.com/toc/icbi20/current")
chrono_coverpage = chronobiology.content

issues = SoupStrainer(id ='tocList')
issues_soup = BeautifulSoup(chrono_coverpage, 'html.parser', parse_only = issues)
for issue in issues_soup:
    print(issue)

返回一个bs4对象 但是 只与 href 从卷的链接 div. 更糟糕的是,这个 div 应包括以下两个方面 div 和问题 div.

所以,我决定尝试减少我的搜索空间,使其更具体,并选择了。div 含有发行的 href 链接 (class_='issues')enter image description here

这个时候木星会思考一下,但不会返回anything。只是空白。什么都没有。Zippo。但是... 如果我问什么类型的 "nothing "已经返回,木星通知它是一个"String"??? 我就不知道该怎么说了。enter image description here

所以,首先我有一个问题,为什么《问题》中的 div 元素不响应解析?当我尝试运行 print(BeautifulSoup(chrono_coverpage, 'html.parser').prettify()) 同样的情况发生,问题 div 不出现(当 Inspect Element 在...上 html 页,它紧贴在最后一卷的下面。span):

enter image description here

所以我怀疑它一定是面向javascript或其他什么的,而不是面向HTML。也可能是 class = 'open' 有什么关系。

如有任何说明,敬请谅解。另外,如何解析Javascript链接来获取它们?

python web-scraping beautifulsoup href
1个回答
0
投票

好的,所以我已经"决心"的问题,不过我需要填补一些理论上的空白。

首先,这个片段是解题的关键所在。

enter image description here

正如我们所看到的 <div class = 'container'> 紧接着是一个 ::before 伪元素和我感兴趣的链接都包含在一个 div 紧挨着这个伪元素的下面。最后这个 div 然后,完成与 ::after 伪元素。

首先我意识到我的问题是我需要选择一个伪元素。我发现这在 BeutifulSoup's soup.select() 既然 BeautifulSoup 用途 Soup Sieve 其中"旨在允许用户使用CSS选择器来锁定XMLHTML元素。它实现了许多伪类[...]。"

该段的最后一部分说:

"汤筛子也不会匹配任何东西的 伪类,只有在实时的浏览器环境中才有意义。, 但如果它们已经实施,它将优雅地处理它们。;"

所以这让我想到,我不知道 "只有在实时浏览器环境下才有意义的伪类 "是什么意思。但我又对自己说:"但它也说,如果实现了它们,BS4应该可以解析它们"。既然我肯定能看到 div 含有我 href 感兴趣的链接 Inspect 工具,我虽说一定要落实。

这句话的第一部分就引起了我的思考。"但我需要一个实时浏览器来工作吗?"

所以这让我想到了 Selenium的网络驱动程序。

import requests
from bs4 import BeautifulSoup, SoupStrainer
from selenium import webdriver

driver = webdriver.Chrome()
url_chronobiology = driver.get("https://www.tandfonline.com/toc/icbi20/current")
chronobiology_content = driver.page_source
chronobiology_soup = BeautifulSoup(chronobiology_content)
chronobiology_soup.select('#tocList > div > div > div.yearContent > div.issues > div > div')
[Out]: []

显然,这个结果让我很伤心,因为我以为我已经明白是怎么回事了。但后来我想,如果我从之前打开的浏览器中 "点击 "其中一个问题,它就会工作(出于某种原因,说实话,我很确定是绝望让我产生了这种想法)。

好吧,我知道了。惊讶 惊喜: 竟然成功了。在点击 "第四期 "后,重新运行... script我得到了我想要的东西。

enter image description here

未回答的问题?

1 - 显然,这些伪元素只有""。存在",否则代码就无法识别它们的存在。为什么要这样做?

2 - 必须运行哪些代码才能进行初始点击并激活这些伪元素,这样代码才能自动打开这些链接并解析我想要的信息?(文章标题)

更新

问题2使用Selenium的ActionChain来回答。

import requests
from bs4 import BeautifulSoup, SoupStrainer
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains

driver = webdriver.Chrome()
url_chronobiology = driver.get("https://www.tandfonline.com/toc/icbi20/current")
chronobiology_content = driver.page_source
chronobiology_soup = BeautifulSoup(chronobiology_content)
action=ActionChains(driver)
action.move_to_element(driver.find_element_by_xpath('//*[@id="tocList"]/div/div/div[3]/div[2]/div')).perform()

chronobiology_soup.select('#tocList > div > div > div.yearContent > div.issues > div > div')
[Out]: 
[<div class="loi-issues-scroller">
 <a class="open" href="/toc/icbi20/37/4?nav=tocList">Issue<span>4</span></a>
 <a class="" href="/toc/icbi20/37/3?nav=tocList">Issue<span>3</span></a>
 <a class="" href="/toc/icbi20/37/2?nav=tocList">Issue<span>2</span></a>
 <a class="" href="/toc/icbi20/37/1?nav=tocList">Issue<span>1</span></a>
 </div>]

唯一的缺点是 是一个人必须留在页面上为 Selenium's ActionChain.perform() 可以实际点击该元素。不过 至少我已经自动完成了这一步。

如果有人能 回答问题1 那就好了

© www.soinside.com 2019 - 2024. All rights reserved.