作为使用Python,Selenium和BeautifulSoup构建的更大的Webscraper的一部分,我试图获取此页面上所有工具提示的文本:https://www.legis.state.pa.us/CFDocs/Legis/BS/bs_action.cfm?SessId=20190&Sponsors=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)命令成功返回了第一个工具提示的文本(“修正1968年1月17日的行为的法案...”),但是随后的每个print(summary)命令仅返回一个空白。
我对编程很陌生,如果有明显答案,就此道歉。
答案 0 :(得分:2)
tl; dr:
不需要硒。如果从字面上看是如图所示的工具提示(不是全文),则可以使用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
}
})
正则表达式:
here试试。
说明:
答案 1 :(得分:0)
该问题可能是由于以下代码行造成的:
summary = driver.find_element_by_class_name("ToolTip-BillSummary-ShortTitle").text
您查找相应元素的条件仅受该元素的类名限制,该条件可能会为您提供元素列表,但实际上您并未指定要获取文本的元素。
要解决此问题,请改用xpath表达式(您需要使用索引变量来定位元素):
summary = driver.find_element_by_xpath("//*[@id="qtip-" + <index> + "-content"]/div/div[3]").text
答案 2 :(得分:0)
如果您使用的是selenium,则不必使用 BeautifulSoup 。要提取页面user
上所有工具提示的文本,可以使用以下解决方案:
代码块:
async
控制台输出:
set