python - 为什么 Selenium 只获取页面上第一个 ToolTip 的文本?
问题描述
作为使用 Python、Selenium 和 BeautifulSoup 构建的大型网络爬虫的一部分,我正在尝试获取此页面上所有工具提示的文本:https ://www.legis.state.pa.us/CFDocs/Legis/BS /bs_action.cfm?SessId=20190&赞助商=S|44|0|Katie%20J.%20Muth
我当前的代码成功地获取了所有链接并将鼠标悬停在每个链接上——当我运行它时,我看到每个工具提示都连续弹出。但是,它只输出第一个工具提示的文本。我不知道为什么!我以为我可能只需要更长的鼠标悬停之间的等待时间,但时间高达 20 秒,但并没有解决问题。
这是代码:
bill_links = soup.find_all('a', {'id': re.compile('Bill')})
summaries = []
bill_numbers = [link.text.strip() for link in bill_links]
for link in bill_links:
billid = link.get('id')
action = ActionChains(driver)
action.move_to_element(driver.find_element_by_id(billid)).perform()
time.sleep(5)
summary = driver.find_element_by_class_name("ToolTip-BillSummary-ShortTitle").text
print(summary)
summaries = summaries + [summary]
action.reset_actions()
同样,第一个 print(summary) 命令成功地返回了第一个工具提示的文本(“An Act amending the act of January 17, 1968...”)——但是每个后续的 print(summary) 命令只返回一个空白。
我对编程很陌生,如果有明显的答案,我深表歉意。
解决方案
tl;博士:
不需要硒。如果它实际上是如图所示的工具提示(不是全文),您可以使用 bs4 并复制页面使用的 javascript 函数。函数调用的参数位于与每个账单列表的 a 标签相邻的脚本标签中。我从适当的字符串中将这些正则表达式传递给我们的用户定义函数(它复制 jquery 函数)
你可以看到相关的调用AddBillSummaryTooltip('#Bill_1',2019,0,'S','B','0012');
工具提示:
import requests
from bs4 import BeautifulSoup as bs
import re
def add_bill_summary_tooltip(s, session_year, session_ind, bill_body, bill_type, bill_no):
url = g_server_url + '/cfdocs/cfc/GenAsm.cfc?returnformat=plain'
data = { 'method' : 'GetBillSummaryTooltip',
'SessionYear' : session_year,
'SessionInd' : session_ind,
'BillBody' : bill_body,
'BillType' : bill_type,
'BillNo' : bill_no,
'IsAjaxRequest' : '1'
}
r = s.get(url, params = data)
soup = bs(r.content, 'lxml')
tooltip = soup.select_one('.ToolTip-BillSummary-ShortTitle')
if tooltip is not None:
tooltip = tooltip.text.strip()
return tooltip
g_server_url = "https://www.legis.state.pa.us"
#add_bill_summary_tooltip('#Bill_1',2019,0,'S','B','0012')
with requests.Session() as s:
r = s.get('https://www.legis.state.pa.us/CFDocs/Legis/BS/bs_action.cfm?SessId=20190&Sponsors=S|44|0|Katie%20J.%20Muth')
soup = bs(r.content, 'lxml')
tooltips = {item.select_one('a').text:item.select_one('script').text[:-1] for item in soup.select('.DataTable td:has(a)')}
p = re.compile(r"'(.*?)',(.*),(.*),'(.*)','(.*)','(.*)'")
for bill in tooltips:
arg1,arg2,arg3,arg4,arg5,arg6 = p.findall(tooltips[bill])[0]
tooltips[bill] = add_bill_summary_tooltip(s, arg2, arg3,arg4,arg5,arg6)
print(tooltips)
全文:
如果您想要全文,那么您可以从第一页获取指向全文页面的链接,然后循环访问每个页面并获取全文:
import requests
from bs4 import BeautifulSoup as bs
def add_bill_summary_full(s, url):
r = s.get(url)
soup = bs(r.content, 'lxml')
summary = soup.select_one('.BillInfo-Section-Data div')
if summary is not None:
summary = summary.text
return summary
g_server_url = "https://www.legis.state.pa.us"
with requests.Session() as s:
r = s.get('https://www.legis.state.pa.us/CFDocs/Legis/BS/bs_action.cfm?SessId=20190&Sponsors=S|44|0|Katie%20J.%20Muth')
soup = bs(r.content, 'lxml')
full_text = {item.text:g_server_url + item['href'] for item in soup.select('.DataTable a')}
for k,v in full_text.items():
full_text[k] = add_bill_summary_full(s, v)
print(full_text)
这是jquery使用的源代码javascript函数
function AddBillSummaryTooltip(element,SessionYear,SessionInd,BillBody,BillType,BillNo) {
jQuery(element).qtip({
content: {
text: function(event, api) {
jQuery.ajax({
url: g_ServerURL + '/cfdocs/cfc/GenAsm.cfc?returnformat=plain',
data: {
method: 'GetBillSummaryTooltip',
SessionYear: SessionYear,
SessionInd: SessionInd,
BillBody: BillBody,
BillType: BillType,
BillNo: BillNo,
IsAjaxRequest: 1
}
})
正则表达式:
在这里试试。
解释:
推荐阅读
- xamarin.forms - Xamarin.Forms DatePicker 对话框颜色自定义
- python - 字典中的 Python 元组值分离
- java - 使用json注释将java字符串点转换为浮点数
- excel - VBA 从类模块中引发错误(使用 Class_Initialize)失败
- java - Java - 通用工厂类
- html - 允许具有预定义大小的重叠图像
- flutter - Flutter stack_trace 使 `catch` 关键字无法工作
- sql - 在 '(' 处或附近出现“语法错误” Postgresql
- javascript - 在js中获取标签的值时出错
- c# - 添加多个托管服务的问题