首页 > 解决方案 > 为什么 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) 命令只返回一个空白。

我对编程很陌生,如果有明显的答案,我深表歉意。

标签: pythonseleniumweb-scrapingactionwebdriverwait

解决方案


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
    					}
                    })


正则表达式:

在这里试试。

解释:

在此处输入图像描述


推荐阅读