使用BeautifulSoup抓取Javascript注入的文本

2024-09-28 21:54:49 发布

您现在位置:Python中文网/ 问答频道 /正文

我想从网页上抓取日期,日期的文本(在脚本标记之后)由JavaScript注入: 我只想用Beautifulsoup而不是selenium来刮

<div class="row">
    <span class="LName"><a target="_blank" href="http://google.com">[me too]</a></span>
    <script language="Javascript" type="text/javascript">formatDate('2020,5,23,09,00,00',1)</script>6/23/2020&nbsp;10:00&nbsp;Tuesday
</div>

这是用于尝试删除日期文本的代码:

headers = {'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:76.0) Gecko/20100101 Firefox/76.0'}
r = requests.get(u, headers=headers)
soup = BeautifulSoup(r.content, 'html.parser')

我尝试:

soup.select('div.row > script')[0].get_text()

返回:

"formatDate('2020,5,23,09,00,00',1)" 

以及:

soup.select('div.row')[0].get_text()

返回:

"\n[me too] formatDate('2020,5,23,09,00,00',1)\n" 

当我使用Chrome检查标记时,我可以看到脚本标记后的日期文本

当我执行:

soup.select('div.row')

它返回不带日期文本的标记

我只想用Beautifulsoup,不想用selenium


Tags: text标记文本div脚本getseleniumscript
3条回答

据我所知,BS根本不呈现Javascript。我使用Selenium获取内容,然后使用BS进行解析。如果您坚持不使用selenium,那么还有其他软件包将首先呈现页面,然后将其提供给BeautifulSoup进行解析

试试看:https://github.com/makinacorpus/spynner 幻影

如果您可以依赖于使用formatDate()函数始终生成的日期,并且可以采用日期显示格式,那么您可以像这样使用BeautifulSoup提取调用,然后使用正则表达式将其解析出来:

import re
date_call = soup.select('div.row > script')[0].get_text()
year, month, day, hour, minutes, seconds, dow = re.search(r"formatDate\('(\d+),(\d+),(\d+),(\d+),(\d+),(\d+)',(\d)\)", date_call).groups()

然后,变量将为您提供重建日期所需的组件:

dow_map = {str(i):dow for i, dow in enumerate(['Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday'])}
date_text = f'{month}/{day}/{year} {h}:{m} {dow_map[dow]}'
import re
from bs4 import BeautifulSoup
from datetime import datetime


txt = '''<div class="row">
    <span class="LName"><a target="_blank" href="http://google.com">[me too]</a></span>
    <script language="Javascript" type="text/javascript">formatDate('2020,5,23,09,00,00',1)</script>6/23/2020&nbsp;10:00&nbsp;Tuesday
</div>'''

soup = BeautifulSoup(txt, 'html.parser')
year, month, day, hour, minutes, sec, *_ = map(int, re.findall(r'\d+', soup.select_one('div.row > script').contents[0]))
d = datetime(year=year, month=month + 1, day=day, hour=hour + 1, minute=minutes, second=sec)
print(datetime.strftime(d, '%m/%d/%Y %H:%M %A'))

印刷品:

06/23/2020 10:00 Tuesday

相关问题 更多 >