【问题标题】:How to yield fragment URLs in scrapy using Selenium?如何使用 Selenium 在 scrapy 中生成片段 URL?
【发布时间】:2017-10-06 11:02:03
【问题描述】:

由于我对网络抓取知之甚少,我发现了一个对我来说非常复杂的问题,我会尽力解释(因此我愿意接受我的帖子中的建议或编辑)。

我很久以前就开始使用网络爬虫框架“Scrapy”来进行网络爬虫,现在我仍然使用它。最近遇到this website,发现我的框架(Scrapy)无法遍历页面,因为这个网站使用Fragment URLs(#)来加载数据(下一页)。然后我就这个问题发了一个帖子(还不知道主要问题):my post

在那之后,我意识到如果没有JavaScript 解释器或浏览器模仿,我的框架就无法实现,所以他们提到了Selenium 库。我尽可能多地阅读有关该库的信息(即example1example2example3example4)。我还发现了这个StackOverflow's post,它提供了一些关于我的问题的线索。

所以最后,我最大的问题是:

1 - 有没有什么方法可以使用 Selenium 和 scrapy 来迭代/生成上面显示的网站的页面? 到目前为止,这是我正在使用的代码,但不起作用...

编辑:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# The require imports...

def getBrowser():
    path_to_phantomjs = "/some_path/phantomjs-2.1.1-macosx/bin/phantomjs"
    dcap = dict(DesiredCapabilities.PHANTOMJS)
    dcap["phantomjs.page.settings.userAgent"] = (
    "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/53 "
    "(KHTML, like Gecko) Chrome/15.0.87")
    browser = webdriver.PhantomJS(executable_path=path_to_phantomjs, desired_capabilities=dcap)

    return browser

class MySpider(Spider):
    name = "myspider"

    browser = getBrowser()

    def start_requests(self):
        the_url = "http://www.atraveo.com/es_es/islas_canarias#eyJkYXRhIjp7ImNvdW50cnlJZCI6IkVTIiwicmVnaW9uSWQiOiI5MjAiLCJkdXJhdGlvbiI6NywibWluUGVyc29ucyI6MX0sImNvbmZpZyI6eyJwYWdlIjoiMCJ9fQ=="

        yield scrapy.Request(url=the_url, callback=self.parse, dont_filter=True)

    def parse(self, response):
        self.get_page_links()

    def get_page_links(self):
        """ This first part, goes through all available pages """

        for i in xrange(1, 3):  # 210
            new_data = {"data": {"countryId": "ES", "regionId": "920", "duration": 7, "minPersons": 1},
                    "config": {"page": str(i)}}
            json_data = json.dumps(new_data)
            new_url = "http://www.atraveo.com/es_es/islas_canarias#" + base64.b64encode(json_data)
            self.browser.get(new_url)
            print "\nThe new URL is -> ", new_url, "\n"
            content = self.browser.page_source
            self.get_item_links(content)

    def get_item_links(self, body=""):
        if body:
            """ This second part, goes through all available items """
            raw_links = re.findall(r'listclickable.+?>', body)
            links = []
            if raw_links:
                for raw_link in raw_links:
                    new_link = re.findall(r'data-link=\".+?\"', raw_link)[0].replace("data-link=\"", "").replace("\"",
                                                                                                             "")
                    links.append(str(new_link))

                if links:
                    ids = self.get_ids(links)
                    for link in links:
                        current_id = self.get_single_id(link)
                        print "\nThe Link -> ", link
                        # If commented the line below, code works, doesn't otherwise
                        yield scrapy.Request(url=link, callback=self.parse_room, dont_filter=True)                                                                           

    def get_ids(self, list1=[]):
        if list1:
            ids = []
            for elem in list1:
                raw_id = re.findall(r'/[0-9]+', elem)[0].replace("/", "")
                ids.append(raw_id)

            return ids

        else:
            return []

    def get_single_id(self, text=""):
        if text:
            raw_id = re.findall(r'/[0-9]+', text)[0].replace("/", "")
            return raw_id

        else:
            return ""

    def parse_room(self, response): 
        # More scraping code...

所以这主要是我的问题。我几乎可以肯定我正在做的不是最好的方法,所以我做了第二个问题。为了避免以后再做这类问题,我做了第三个问题。

2 - 如果第一个问题的答案是否定的,我该如何解决这个问题?我愿意接受另一种方式,否则

3 - 谁能告诉我或展示我可以学习如何解决/结合使用 javaScript 和 Ajax 的网页抓取的页面?现在越来越多的网站使用 JavaScript 和 Ajax 脚本来加载内容

非常感谢!

【问题讨论】:

标签: javascript python selenium web-scraping scrapy


【解决方案1】:

Selenium 是抓取动态数据的最佳工具之一。您可以在任何 Web 浏览器中使用 selenium 来获取从脚本加载的数据。它的工作原理与浏览器单击操作完全相同。但我不喜欢它。

要获取动态数据,您可以使用 scrapy + splash 组合。从 scrapy 你会得到所有的静态数据和其他动态内容的飞溅。

【讨论】:

  • 非常感谢您的回答。但是,为了得到更具体的答案,我对我的帖子进行了一些编辑,请看一下! @Arun 奥古斯丁 :)
【解决方案2】:

你看过 BeautifulSoup 吗?这是一个非常流行的 Python 网页抓取库。至于 JavaScript,我会推荐 Cheerio 之类的东西(如果你要求 JavaScript 中的抓取库)

如果您的意思是网站使用 HTTP 请求来加载内容,您可以随时尝试使用 requests 库之类的东西手动操作。

希望对你有帮助

【讨论】:

  • 感谢朋友的回答,但我已经对我的帖子进行了一些编辑,如果你想要@JC1,请再看一遍
【解决方案3】:

您绝对可以单独使用 Selenium 来废弃具有动态内容(如 AJAX 加载)的网页。

Selenium 将仅依靠 WebDriver(基本上是 Web 浏览器)在 Internet 上搜索内容。

以下是其中一些(但最常用的)

  • Chrome 驱动程序
  • PhantomJS(我的最爱)
  • 火狐

启动后,您可以启动机器人并解析网页的 html 内容。

我在下面包含了一个使用 Python 和 ChromeDriver 的最小工作示例:

from selenium import webdriver
from selenium.webdriver.common.by import By


driver = webdriver.Chrome(executable_path='chromedriver')
driver.get('https://www.google.com')
# Then you can search for any element you want on the webpage
search_bar = driver.find_element(By.CLASS_NAME, 'tsf-p')
search_bar.click()
driver.close()

详情请见the documentation

【讨论】:

  • 我或多或少知道你写了什么。我已经对我的帖子进行了一些编辑,请再次查看@rak007
猜你喜欢
  • 2017-09-05
  • 1970-01-01
  • 2016-09-18
  • 1970-01-01
  • 1970-01-01
  • 2014-04-12
  • 2016-12-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多