Python 使用BeautifulSoup检查动态生成的页面上是否存在字符串

Python 使用BeautifulSoup检查动态生成的页面上是否存在字符串,python,beautifulsoup,screen-scraping,Python,Beautifulsoup,Screen Scraping,我正在检查Twitter.com上某个帐户的状态。该网站没有使用清晰的容器名称,因为它们是动态生成的。我想是这样,我是在匹配文本字符串。受启发,我希望以下代码能够工作,但它返回一个空列表: import requests from bs4 import BeautifulSoup page = requests.Session().get('https://twitter.com/MikeEPeinovich') page = page.content soup = BeautifulSoup(

我正在检查Twitter.com上某个帐户的状态。该网站没有使用清晰的容器名称,因为它们是动态生成的。我想是这样,我是在匹配文本字符串。受启发,我希望以下代码能够工作,但它返回一个空列表:

import requests
from bs4 import BeautifulSoup
page = requests.Session().get('https://twitter.com/MikeEPeinovich')
page = page.content
soup = BeautifulSoup(page, "lxml")
print soup.findAll(text="Account suspended")
…下面是一个使用不同请求库和HTML解析器的变体(尽管最终结果相同):

对我做错了什么有什么建议吗?谢谢

更新

下面有人正确地向我指出,我需要类似Selenium的东西来模拟浏览器行为,以便捕获完全加载的动态网页对象,因此我将Selenium和Mozilla的Gecko浏览器集成到脚本中。不过,在检查
对象时,我显然还没有抓住所有东西。这是我现在使用的脚本:

# With Selenium
from bs4 import BeautifulSoup
from selenium.webdriver.firefox.options import Options as FirefoxOptions
from selenium import webdriver

url = "https://twitter.com/MikeEPeinovich"

options = FirefoxOptions()
options.add_argument("--headless")
browser = webdriver.Firefox(options=options)
browser.get(url)
html = browser.page_source
soup = BeautifulSoup(html, 'lxml')
print soup.findAll(text="Account suspended")

那是因为绳子真的不在那里。BeautifulSoup仅对通常缺少某些内容的页面发出初始请求(其他内容由JavaScript加载)。如果您进入问题中提到的页面并按Control+u,您将不会在那里找到字符串
“Account suspended”
。这是
请求的
库看到的相同html

作为一种解决方案,您可以使用Selenium加载网页,就像在浏览器中一样。或者,您可以转到浏览器开发工具中的
网络
选项卡,查看Twitter在后台执行的请求。我检查了它,并在其中一个请求中检索到了帐户信息,但我无法在Postman中复制该请求(这并不奇怪,像Twitter这样的大型网站必须具有良好的安全性)

更新:


例如,请参见此问题:

页面是由
Javascript
生成的

因此,您可以使用ajax API(使用带有一些参数的正确标题),如:

要获取错误消息,请执行以下操作:

Authorization: User has been suspended. (63)

如果你打印
页面
,你会得到一大堆
脚本
标签,指示页面使用javascript加载内容(包括你正在搜索的文本)。谢谢你的输入。我已经将Selenium和Firefox的无头浏览器Gecko Browser集成到我的脚本中,但是当我检查返回的
soup
对象时,该字符串仍然不在其中,因此我怀疑我需要处理加载时间参数或其他一些…优雅的东西。但是,我怀疑这可能会在
cookie
authorization
头过期后停止工作。不久前我遇到了这个问题,并这样解决了它:首先我用
request
做了一个普通请求,从中我得到了
cookie
值。然后,我将
cookie
值插入到标题中,它起作用了。@druskacik由于cookie将过期,这只会起作用一段时间。要接收带有
请求
模块的cookie,可能需要
请求。会话
并需要像浏览器那样发送请求。
import requests

headers = {
    'x-csrf-token': '11a1d4eb65d6b52fb22ef8c0377013bf',
    'authorization': 'Bearer AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA',
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36',
    'x-guest-token': '1335956221107572737',
    'cookie': 'personalization_id="v1_/4NldbdRSml+BviPBqfJVg=="; guest_id=v1%3A160735174410977274; ct0=11a1d4eb65d6b52fb22ef8c0377013bf; _twitter_sess=BAh7CSIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxlcjo6Rmxhc2g6OkZsYXNo%250ASGFzaHsABjoKQHVzZWR7ADoPY3JlYXRlZF9hdGwrCLdgoT12AToMY3NyZl9p%250AZCIlN2I4Y2YzMThjODBkZmQ5NjkzMGQyN2UyNTZmODAxMGQ6B2lkIiU1OWYw%250ANjc5OWI5OGMyYmViOGNlMWE0ZWNkNzdiMjQyYw%253D%253D--ea9af5c4c148aee6204c39ddd96cc43125ee9893; gt=1335956221107572737',
}

username = "MikeEPeinovich"

params = (
    ('variables', '{"screen_name":"MikeEPeinovich","withHighlightedLabel":true}'),
)

response = requests.get('https://api.twitter.com/graphql/esn6mjj-y68fNAj45x5IYA/UserByScreenName', headers=headers, params=params)
print(response.json()["errors"][0]["message"])
Authorization: User has been suspended. (63)