首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当我尝试使用请求库进行web抓取时,为什么会得到一个空的body标签内容?

当我尝试使用请求库进行web抓取时,为什么会得到一个空的body标签内容?
EN

Stack Overflow用户
提问于 2021-06-07 20:39:18
回答 2查看 47关注 0票数 3

我一直在尝试在一个网站上使用web抓取,使用的是requests和Beautifulsoup python库。问题是,我正在获取网页的html数据,但是body标签内容是空的,而在网站上的检查面板上却不是。有人能解释为什么会发生这种情况吗?我可以做些什么来获取body的内容?

下面是我的代码:

代码语言:javascript
复制
from bs4 import BeautifulSoup
import requests

source = requests.get('https://webaccess-il.rexail.com/?s_jwe=eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0..gKfb7AnqhUiIMIn0PGb35g.SUsLS70gBec9GBgraaV5BK8hKyqm-VvMSNjP3nIumtcrj9h19zOkYjaBHrW4SDL10DjeIcwQcz9ul1p8umMHKxPPC-QZpCyJbk7JQkUSqFM._d_sGsiSyPF_Xqs2hmLN5A#/store-products-shopping-non-customers').text
soup = BeautifulSoup(source, 'lxml')
print(soup)

以下是该网站的检查面板:

下面是我的代码的输出:

谢谢您:)

EN

回答 2

Stack Overflow用户

发布于 2021-06-07 21:12:54

有两个原因,你的代码不能工作。第一个问题是,网站确实需要额外的headercookie信息,您可以尝试使用Inspect Browser工具查找这些信息并通过添加

代码语言:javascript
复制
requests.get(url, headers=headers, cookies=cookies)

其中headerscookies是字典。

另一个原因,我相信是这样的,那就是在构建完网站后,内容会通过Javascript动态加载,而你得到的是最初加载的网站。

为了给你提供一个解决方案,我附上了一个使用Selenium的例子,它模拟了一个完整的浏览器,它确实为整个网站提供服务,但是selenium有一些设置开销,你可以很容易地谷歌一下。

代码语言:javascript
复制
from time import sleep
from selenium import webdriver
from bs4 import BeautifulSoup
url = 'https://webaccess-il.rexail.com/?s_jwe=eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0..gKfb7AnqhUiIMIn0PGb35g.SUsLS70gBec9GBgraaV5BK8hKyqm-VvMSNjP3nIumtcrj9h19zOkYjaBHrW4SDL10DjeIcwQcz9ul1p8umMHKxPPC-QZpCyJbk7JQkUSqFM._d_sGsiSyPF_Xqs2hmLN5A#/store-products-shopping-non-customers'
driver = webdriver.Firefox()
driver.get(url)
sleep(10)
content = driver.page_source
soup = BeautifulSoup(content)

如果希望浏览器模拟不可见,可以添加

代码语言:javascript
复制
from selenium.webdriver.firefox.options import Options
options = Options()
options.headless = True
driver = webdriver.Firefox(options=options)

这将使它在后台运行。

作为Firefox的替代方案,您可以使用几乎任何使用适当驱动程序的浏览器。

可以在Link中找到基于Linux的安装示例。

票数 1
EN

Stack Overflow用户

发布于 2021-06-07 22:21:24

尽管我发现Selenium的使用对于初学者来说更容易,但这个网站让我很困扰,所以我找到了一种纯粹的requests方式,我也想分享一下。

流程:当你在加载网站后查看网络流量时,你会发现有很多传出的get请求。假设您对已加载的产品感兴趣,我在从亚马逊S3加载的产品图像上方找到了一个调用,该调用将转到

代码语言:javascript
复制
https://client-il.rexail.com/client/public/public-catalog?s_jwe=eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0..gKfb7AnqhUiIMIn0PGb35g.SUsLS70gBec9GBgraaV5BK8hKyqm-VvMSNjP3nIumtcrj9h19zOkYjaBHrW4SDL10DjeIcwQcz9ul1p8umMHKxPPC-QZpCyJbk7JQkUSqFM._d_sGsiSyPF_Xqs2hmLN5A

重要的是

代码语言:javascript
复制
https://client-il.rexail.com/client/public/public-catalog?s_jwe=[...]

单击URL后,我发现它确实是产品的JSON。但是,s_jwe令牌是动态的,如果没有它,就不会加载。

现在研究初始加载的url并搜索s_jwe,您将会发现

代码语言:javascript
复制
<script>
            window.customerStore = {store: angular.fromJson({"id":26,"name":"\u05de\u05e9\u05e7 \u05d4\u05e8 \u05e4\u05e8\u05d7\u05d9\u05dd","imagePath":"images\/stores\/26\/88aa6827bcf05f9484b0dafaedf22b0a.png","secondaryImagePath":"images\/stores\/4d5d1f54038b217244956071ca62312d.png","thirdImagePath":"images\/stores\/26\/2f9294180e7d656ba7280540379869ee.png","fourthImagePath":"images\/stores\/26\/bd2861565b18613497a6ce66903bf9eb.png","externalWebTrackingAccounts":"[{\"accountType\":\"googleAnalytics\",\"identifier\":\"UA-130110792-1\",\"primaryDomain\":\"ecomeshek.co.il\"},{\"accountType\":\"facebookPixel\",\"identifier\":\"3958210627568899\"}]","worksWithStoreCoupons":false,"performSellingUnitsEstimationLearning":false}), s_jwe: "eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0..gKfb7AnqhUiIMIn0PGb35g.SUsLS70gBec9GBgraaV5BK8hKyqm-VvMSNjP3nIumtcrj9h19zOkYjaBHrW4SDL10DjeIcwQcz9ul1p8umMHKxPPC-QZpCyJbk7JQkUSqFM._d_sGsiSyPF_Xqs2hmLN5A"};
            const externalWebTrackingAccounts = angular.fromJson(customerStore.store.externalWebTrackingAccounts);
        </script>

包含

代码语言:javascript
复制
s_jwe: "eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0..gKfb7AnqhUiIMIn0PGb35g.SUsLS70gBec9GBgraaV5BK8hKyqm-VvMSNjP3nIumtcrj9h19zOkYjaBHrW4SDL10DjeIcwQcz9ul1p8umMHKxPPC-QZpCyJbk7JQkUSqFM._d_sGsiSyPF_Xqs2hmLN5A"

因此,总结一下,尽管初始页面不包含产品,但它确实包含令牌和产品url。

现在您可以提取这两个文件并直接调用产品目录,如下所示:

最终代码:

代码语言:javascript
复制
import requests
import re
import json

s = requests.Session()

initial_url = 'https://webaccess-il.rexail.com/?s_jwe=eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0..gKfb7AnqhUiIMIn0PGb35g.SUsLS70gBec9GBgraaV5BK8hKyqm-VvMSNjP3nIumtcrj9h19zOkYjaBHrW4SDL10DjeIcwQcz9ul1p8umMHKxPPC-QZpCyJbk7JQkUSqFM._d_sGsiSyPF_Xqs2hmLN5A#/store-products-shopping-non-customers'
initial_site = s.get(url= initial_url).content.decode('utf-8')

jwe = re.findall(r's_jwe:.*"(.*)"', initial_site)

product_url = "https://client-il.rexail.com/client/public/public-catalog?s_jwe="+ jwe[0]
products_site = s.get(url= product_url).content.decode('utf-8')
products = json.loads(products_site)["data"]
print(products[0])

解码需要一些微调,但我相信你可以做到。;)

这当然是更精简的抓取网站的方式,但正如我所希望的那样,抓取总是有点像夏洛克·福尔摩斯。

有任何问题,很乐意为您效劳。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67871777

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档