在XPath中按类别和范围进行搜索

时间:2018-11-02 02:42:00

标签: python selenium xpath

我目前正在做一个Google Play商店抓取工具,可抓取特定应用程序的评论并将评论写到文件中。为此,我使用Python Selenium在这里搜索所有评论:https://play.google.com/store/apps/details?id=com.grabtaxi.passenger&showAllReviews=true,然后提取出所有评论。

所有评论都被确定在特定的类zc7KVe中,因此我确定用于获取所有评论的XPath是: //div[@class='zc7KVe']

这是Python中用于使用上述XPath查找此类元素的代码行,它是在while循环内完成的: reviews = driver.find_elements(By.XPATH, '//div[@class=\'zc7KVe\']'

问题是,当我继续向下滚动页面时,reviews变量的长度越来越大。这是因为上面的XPath搜索满足条件的所有元素。这会导致抓取操作所需的时间呈指数增长(例如,向下滚动页面80次后,抓取240组新评论要花20分钟以上,而我刚开始时需要30秒)。

为了使其速度更快,我正在探索将position()包含在XPath内,以便不需要提取出满足条件的所有元素。我研究了this,并尝试在//div[contains(@class,'zc7KVe') and (position() >= 100) and not (position > 200)]之类的Chrome DevTools中测试XPath,但无济于事。

是否有一个XPath可以满足特定类以及范围的搜索需求?

添加

在DevTools中进行检查时,HTML的结构应如下所示:

<div jscontroller="..." jsmodel="..." jsdata="..." ...>
    <div class="zc7KVe">
        <!-- One review -->
<div jscontroller="..." jsmodel="..." jsdata="..." ...>
    <div class="zc7KVe">
        <!-- One review -->
<!-- and so on -->

1 个答案:

答案 0 :(得分:2)

这里有多种提高性能的方法:

  • 首先向上滚动,直到获得所有评论(或一定数量),然后然后将其提取
  • 让HTML解析器执行HTML解析,这将使您减少JSON over HTTP硒命令的数量以及通过硒webdriver查找元素的其他开销。您可以获取审阅部分的内部/外部HTML并使用BeautifulSoup进行解析。遵循以下原则:

      <div class="container" id="mainBody">
       <div class="row text-center" style="display:flex; flex-wrap:wrap;">
        <% songs.forEach(function(song){%>
            <div class="col-md-4 col-sm-6">
                <div class="thumbnail">
                    <div class="player">
                        <!--<div class="pl"></div>-->
                        <!--<div class="title"></div>-->
                        <div class="cover"></div>
                        <div class="bottom_section">
                            <div class= "controls">
                                ...play buttons go here...
    
                                ..js mp3 js file goes here right after..
    
  • 记住您从中获得评论的最后一个元素,并使用following-sibling axis提取该元素后面的兄弟姐妹
  • 您还可以研究 Google Play API 和官方或非官方客户(例如this one),这可以帮助您从不同的角度看问题。
  • ,并且,如果您仍想使用XPath方法并使用 <% if(song) { %> <script type="text/javascript"> $(document).ready(function(){ $(".player").each(function(index){ var track = new Audio(); track.src="<%=song%>"; $(".mainB").click(function(){ if(track.paused){ track.play(); $(this).toggleClass('fa fa-play fa fa-pause'); } else{ track.pause(); $(this).toggleClass('fa fa-pause fa fa-play'); } }); }); }); </script> <% } %> 来按“范围”过滤掉内容,则可以在包含评论的容器范围内操作:< / p>

    In [8]: reviews = driver.find_element_by_xpath("//h3[. = 'User reviews']/following-sibling::div[1]")
    
    In [9]: soup = BeautifulSoup(reviews.get_attribute("outerHTML"), "lxml")
    
    In [10]: for review in soup.div.find_all("div", jscontroller=True, recursive=False):
                 author = review.find(class_="X43Kjb").get_text()
                 print(author)   
    Angie Lin
    Danai Sae-Han
    Siwon's Armpit Hair
    Vishal Mehta
    Ann Leong
    V. HD
    Mark Stephen Masilungan 
    ...
    Putra Pandu Adikara
    kei tho
    Phụng Nguyễn