【问题标题】:Python web scaping recursively (next page)Python web 递归抓取(下一页)
【发布时间】:2019-04-06 18:12:23
【问题描述】:

来自这个网站: https://search2.ucl.ac.uk/s/search.html?query=max&collection=website-meta&profile=_directory&tab=directory&f.Profile+Type%7Cg=Student&start_rank=1

我需要使用 Selenium 或 LXML 抓取下一页 2、3 ...。 我只能刮第一页

【问题讨论】:

    标签: python selenium web-scraping lxml


    【解决方案1】:

    你可以试试这个:

    nextNumberIsThere = True
    i=1
    while nextNumberIsThere:
        driver.execute_script("document.body.scrollHeight");
        profileDetails = driver.find_elements_by_xpath("//ul[@class='profile-details']/li")
        for element in profileDetails:
            print(element.text)
        next = driver.find_elements_by_xpath("//a[text()='"+str(i)+"']")
        i+=1
        if len(next) > 0:
            next[0].click()
        else:
            nextNumberIsThere = False
    

    上述代码将迭代并获取数据,直到没有剩余数字为止。

    如果您想分别获取姓名、部门、​​电子邮件,请尝试以下代码:

    nextNumberIsThere = True
    i=1
    while nextNumberIsThere:
        driver.execute_script("document.body.scrollHeight");
        profileDetails = driver.find_elements_by_xpath("//ul[@class='profile-details']")
        for element in profileDetails:
            name = element.find_element_by_xpath("./li[@class='fn']")
            department = element.find_elements_by_xpath("./li[@class='org']")
            email = element.find_element_by_xpath("./li[@class='email']")
            print(name.text)
            print(department.text)
            print(email.text)
            print("------------------------------")
            next = driver.find_elements_by_xpath("//a[text()='"+str(i)+"']")
        i+=1
        if len(next) > 0:
            next[0].click()
        else:
            nextNumberIsThere = False
    

    希望对你有帮助……

    【讨论】:

      【解决方案2】:

      【讨论】:

      • 是的,我已经做了,但是我不知道什么时候停止,我的意思是最后一页是50还是40;因为我将为每个名称的可用页数创建一个循环,我不知道每个名称有多少页:例如,如果我们搜索“alex”search2.ucl.ac.uk/s/…
      • 我认为对于给定的查询,您不能看到超过 50 个结果。如果是这种情况,您可以优化查询,并使用可用的排序,直到您的搜索结果
      【解决方案3】:

      此类问题的通常解决方案不是使用循环遍历“所有页面”(因为您不知道预先有多少页面),而是使用某种队列,其中抓取一页可以选择将后续页面添加到队列中,以便稍后抓取。

      在您的具体示例中,在抓取每个页面的过程中,您可以查找指向“下一页”的链接,如果存在,则将下一页的 URL 添加到队列中,这样它将在当前页面之后被抓取;一旦您点击没有“下一页”链接的页面,队列将清空并且抓取将停止。 一个更复杂的例子可能包括抓取一个类别页面并将其每个子类别作为后续页面添加到抓取队列中,每个子类别又可能将多个项目页面添加到队列中,等等。

      看看像Scrapy 这样的抓取框架,它们很容易在设计中包含这种功能。您可能会发现它的一些其他功能也很有用,例如它能够使用 XPath 或 CSS 选择器在页面上查找元素。

      Scrapy 主页上的第一个示例准确地显示了您尝试实现的功能类型:

      class BlogSpider(scrapy.Spider):
          name = 'blogspider'
          start_urls = ['https://blog.scrapinghub.com']
      
          def parse(self, response):
              for title in response.css('.post-header>h2'):
                  yield {'title': title.css('a ::text').get()}
      
              for next_page in response.css('a.next-posts-link'):
                  yield response.follow(next_page, self.parse)
      

      关于 Scrapy 的一个重要说明:它不使用 Selenium(至少不是开箱即用的),而是下载页面源并对其进行解析。这意味着它不运行 JavaScript,如果您正在抓取的网站是客户端生成的,这对您来说可能是个问题。在这种情况下,您可以研究结合 Scrapy 和 Selenium 的解决方案(快速谷歌搜索显示了一堆,以及有关此问题的 StackOverflow 答案),或者您可以坚持使用您的 Selenium 抓取代码并自己实现排队机制,而无需刮痧。

      【讨论】:

      • 对于他正在抓取的网站,这是行不通的,因为next 按钮永远不会消失。事实上,在页面5 之后next 只是再次重定向到第五页,并且循环永远不会结束。一种选择可能是检查一个页面的结果是否与以前的结果相同,或者像我建议的那样简单地抓取前 5 页或 50 个结果。如果我有兴趣收集尽可能多的数据,我会优化查询并使用排序
      猜你喜欢
      • 2021-08-29
      • 1970-01-01
      • 1970-01-01
      • 2014-09-15
      • 1970-01-01
      • 2019-09-23
      • 1970-01-01
      • 1970-01-01
      • 2023-03-23
      相关资源
      最近更新 更多