【问题标题】:Scraping a website with data hidden under "read more"抓取隐藏在“阅读更多”下的数据的网站
【发布时间】:2019-06-20 08:53:37
【问题描述】:

我正在尝试从 Tripadvisor.com 抓取评论,我想在网站的“阅读更多”按钮下获取数据。有没有办法在不使用硒的情况下刮掉这个?

到目前为止,这是我使用的代码

resp = requests.get('https://www.tripadvisor.com.ph/Hotel_Review-g8762949-d1085145-Reviews-El_Rio_y_Mar_Resort-San_Jose_Coron_Busuanga_Island_Palawan_Province_Mimaropa.html#REVIEWS') 
rsp_soup = BeautifulSoup(resp.text, 'html.parser')
rsp_soup.findAll(attrs={"class": "hotels-review-list-parts-ExpandableReview__reviewText--3oMkH"})

但它无法抓取“阅读更多”下的内容

【问题讨论】:

  • 到目前为止你的代码是什么?

标签: python web-scraping beautifulsoup


【解决方案1】:

评论部分显示在 html 中,直到您单击 read more,它实际上不会进行 Ajax 调用,而是根据 window.__WEB_CONTEXT__ 中包含的数据更新页面。您可以通过查看它所在的 <script> 标记来访问此数据:

<script>
     window.__WEB_CONTEXT__={pageManifest:{"assets":["/components/dist/@ta/platform.polyfill.084d8cdf5f.js","/components/dist/runtime.56c5df2842.js", ....  }
</script>

一旦你得到它,你和你就可以提取和处理 JSON 格式的数据。完整代码如下:

import json
from bs4 import BeautifulSoup
resp = requests.get('https://www.tripadvisor.com.ph/Hotel_Review-g8762949-d1085145-Reviews-El_Rio_y_Mar_Resort-San_Jose_Coron_Busuanga_Island_Palawan_Province_Mimaropa.html#REVIEWS') 

data = BeautifulSoup(resp.content).find('script', text = re.compile('window.__WEB_CONTEXT__')).text

#Some text processing to make the tag content a valid json
pageManifest = json.loads(data.replace('window.__WEB_CONTEXT__=','').replace('{pageManifest:', '{"pageManifest":')[:-1])


for x in pageManifest['pageManifest']['apolloCache']:
    try:
        reviews = x['result']['locations'][0]['reviewList']['reviews']       
    except:
        pass

print([x['text'] for x in reviews])

输出

['Do arrange for airport transfers! From the airport, you will be taking a van for around 20 minutes, then you\'ll be transferred to a banca/boat for a 25 minute ride to the resort. Upon arrival, you\'ll be greeted by a band that plays their "welcome, welcome" song and in our case, we were met by Maria (awesome gal!) who introduced the group to the resort facilities and checks you in at the bar.I booked a deluxe room, which is actually a duplex with 2 adjoining rooms, ideal
for families, which accommodates 4 to a room.Rooms are clean and bed is comfortable.Potable water is provided upon check in , but is chargeable thereafter.Don\ 't worry, ...FULL REVIEW...',
 "Stayed with my wife and 2 children, 10y and 13y. ...FULL REVIEW...",
 'Beginning at now been in Coron for a couple of   ...FULL REVIEW...',
 'This was the most beautiful and relaxing place   ...FULL REVIEW...',
 'We spent 2 nights at El rio. It was incredible,  ...FULL REVIEW... ']

【讨论】:

    【解决方案2】:

    一般来说,不会。这完全取决于您点击“阅读更多”时会发生什么,即实际数据在哪里

    通常有两种可能性(不相互排斥):

    • 数据位于同一页面,隐藏,“阅读更多”是例如隐藏复选框的标签,选中后,隐藏“阅读更多”范围并显示其余文本。这种方式显示的页面更小,更易读,但它都是在同一个调用中加载的。在这种情况下,您只需要找到一个合适的选择器(例如 #someotherselector+input[type=checkbox] ~ div.moreText 或类似的东西)。
    • 数据不存在,它会在一段时间后通过 AJAX 加载,保持隐藏状态,或者只有在单击“阅读更多”时才会显示。这允许保留一个快速加载的小页面,但包含大量加载缓慢的项目,在后台或按需加载它们。在这种情况下,您需要检查实际的 AJAX 调用(它通常带有 id 或保存在 'Load More...' 元素中的数据值:&lt;span class="loadMore" data-text-id="x19834"&gt;Read more...&lt;/span&gt;)并使用适当的标题发出相同的调用:

      resp2 = requests.get('https://www.tripadvisor.com.ph/whatever/api/is/used?id=' + element.attr('data-text-id'))

    在不知道如何检索数据以及相关元素(例如,携带 id 的属性的名称和内容等)在哪里的情况下,不可能给出每次都有效的答案。

    您也可能对doing this the right way 感兴趣。您抓取的数据受版权保护,TripAdvisor 可能会做出足够的改变,以至于您在维护抓取工具时会遇到问题。

    【讨论】:

      猜你喜欢
      • 2021-07-27
      • 1970-01-01
      • 2021-06-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-11
      • 1970-01-01
      相关资源
      最近更新 更多