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

2024-09-28 22:21:37 发布

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

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

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解析器的变体(尽管最终结果相同):

import urllib2
from bs4 import BeautifulSoup

page = urllib2.urlopen('https://twitter.com/MikeEPeinovich')
soup = BeautifulSoup(page, "html.parser")
print soup.findAll(text="Account suspended")

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

更新

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

# 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")

Tags: textfromhttpsimportcompagetwitteraccount
2条回答

页面由Javascript生成

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

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)

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

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

更新:

例如,见这个问题:Wait page to load before getting data with requests.get in python 3

相关问题 更多 >