python - 动态 CSS 选择器如何与 Beautiful Soup 一起使用?
问题描述
以下代码从siteUrlArray
. 它工作正常。
然而,这需要我为每个网站编写一个函数——只是为了定义选择器。我尝试动态构建
soup.find
并soup.select
使用 exec 和 dict 来保存选择器变量 - 但我无法让它工作。
工作代码
from bs4 import BeautifulSoup
import requests
import sys
import tldextract
def processmarketbeat(soup):
try:
mbtSel = soup.findAll("div", {"id": "cphPrimaryContent_tabAnalystRatings"})[0].find("table")
print(mbtSel)
except Exception as e:
print(str(e))
def processwsj(soup):
try:
wsjSel = soup.select('.at8-col4 > .zonedModule')[0]
print(wsjSel)
except Exception as e:
print(str(e))
global siteUrl, domain, header, parser
header = {'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:32.0) Gecko/20100101 Firefox/32.0',}
parser = 'html.parser'
siteUrlArray = ['http://www.marketbeat.com/stocks/NASDAQ/GOOGL/price-target',
'http://www.wsj.com/market-data/quotes/GOOGL/research-ratings',
'http://www.marketbeat.com/stocks/NASDAQ/SQ/price-target',
'http://www.wsj.com/market-data/quotes/SQ/research-ratings']
for i in range(len(siteUrlArray)):
siteUrl = siteUrlArray[i]
parsedUrl = tldextract.extract(siteUrl)
domain = parsedUrl.domain
r = requests.get(siteUrl, headers=header, verify=False)
soup = BeautifulSoup(r.text, parser)
getattr(sys.modules[__name__], "process%s" % domain)(soup)
尝试使用动态选择器
stockDict = {
'marketbeat': '"""x = soup.findAll("div", {"id": "cphPrimaryContent_tabAnalystRatings"})[0].find("table")"""',
'wsj': '"""x = soup.select(".at8-col4 > .zonedModule")[0]"""'
}
header = {'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:32.0) Gecko/20100101 Firefox/32.0',}
parser = 'html.parser'
siteUrlArray = ['http://www.marketbeat.com/stocks/NASDAQ/GOOGL/price-target',
'http://www.wsj.com/market-data/quotes/GOOGL/research-ratings',
'http://www.marketbeat.com/stocks/NASDAQ/SQ/price-target',
'http://www.wsj.com/market-data/quotes/SQ/research-ratings']
for i in range(len(siteUrlArray)):
siteUrl = siteUrlArray[i]
parsedUrl = tldextract.extract(siteUrl)
domain = parsedUrl.domain
r = requests.get(siteUrl, headers=header, verify=False)
soup = BeautifulSoup(r.text, parser)
selector = stockDict.get(domain)
exec(selector)
# I want the EXEC to run the equivalent of
# x = soup.findAll("div", {"id": "cphPrimaryContent_tabAnalystRatings"})[0].find("table")
# so that I can print the tags as print(x)
print(x)
但是 x 打印为 None 而不是所选对象的 HTML 代码。
解决方案
我能够使用以下代码实现我想要做的事情:
selectorDict = {
'marketbeat': 'x = soup.findAll("div", {"id": "cphPrimaryContent_tabAnalystRatings"})[0].find("table")\nprint(x)',
'wsj': 'x = soup.select(".at8-col4 > .zonedModule")[0]\nprint(x)'
}
for i in range(len(siteUrlArray)):
siteUrl = siteUrlArray[i]
print(siteUrl)
parsedUrl = tldextract.extract(siteUrl)
domain = parsedUrl.domain
r = requests.get(siteUrl, headers=header, verify=False)
soup = BeautifulSoup(r.text, parser)
selector = selectorDict.get(domain)
try:
exec(selector)
except Exception as e:
print(str(e))
推荐阅读
- android - 两个或多个带有进度的前台通知在更新进度时相互替换
- python - 使用 itemcget 在 tkinter 中获取单个列表框项属性?
- android - 固定状态栏和隐藏导航栏
- reactjs - 在 React 上使用段并调用“analytics.default.track”错误“超出最大调用堆栈大小”
- python - Django:芹菜任务不使用 .delay() 执行
- typescript - 在 Ant Design React Typescript 项目中添加对 LESS 模块的支持
- symfony4 - symfony 4 - “属性 App\\Model\\BaseCar::$model 不存在”
- r - 如何在R中导入matlab表
- python - 如何比较两个 GLCM 以找到相似之处?
- symfony - SonataUserBundle + FOSUserBundle 覆盖表名或前缀 - Symfony 4