【问题标题】:best practice for navigating through hrefs with scrapy使用 scrapy 浏览 href 的最佳实践
【发布时间】:2017-01-20 03:08:57
【问题描述】:

我正在构建一个从网站下载 csv 文件的网络 scraper。我必须登录多个用户帐户才能下载所有文件。我还必须浏览几个 href 才能访问每个用户帐户的这些文件。我决定使用 Scrapy 蜘蛛来完成这项任务。这是我到目前为止的代码:

我将用户名和密码信息存储在字典中

 def start_requests(self):
    yield scrapy.Request(url = "https://external.lacare.org/provportal/", callback = self.login)

 def login(self, response):
    for uname, upass in login_info.items():      
        yield scrapy.FormRequest.from_response(
            response,
            formdata = {'username': uname,
                        'password': upass,
                        },
            dont_filter = True,
            callback = self.after_login
            )

然后我通过在每个响应中查找所有 href 链接来浏览网页。

def after_login(self, response):
    hxs = scrapy.Selector(response)
    all_links = hxs.xpath('*//a/@href').extract()
    for link in all_links:
        if 'listReports' in link:
            url_join = response.urljoin(link)
            return scrapy.Request(
                url = url_join,
                dont_filter = True,
                callback = self.reports
                )
    return

def reports(self, response):
    hxs = scrapy.Selector(response)
    all_links = hxs.xpath('*//a/@href').extract()
    for link in all_links:
        url_join = response.urljoin(link)
        yield scrapy.Request(
            url = url_join,
            dont_filter = True,
            callback = self.select_year
            )
            
    return

然后我爬取页面上的每个 href 并检查响应,看看我是否可以继续。这部分代码对我来说似乎过多,但我不知道如何处理它。

def select_year(self, response):
    if '>2017' in str(response.body):
        hxs = scrapy.Selector(response)
        all_links = hxs.xpath('*//a/@href').extract()
        for link in all_links:
            url_join = response.urljoin(link)
            yield scrapy.Request(
                url = url_join,
                dont_filter = True,
                callback = self.select_elist
                )
    return

 def select_elist(self, response):
    if '>Elists' in str(response.body):
        hxs = scrapy.Selector(response)
        all_links = hxs.xpath('*//a/@href').extract()
        for link in all_links:
            url_join = response.urljoin(link)
            yield scrapy.Request(
                url = url_join,
                dont_filter = True,
                callback = self.select_company
                )

一切正常,但正如我所说,爬过页面上的每个 href 似乎有点过分。我在 Selenium 中为这个网站编写了一个脚本,并且能够通过使用 select_by_partial_link_text() 方法选择正确的 href。我在scrapy中搜索过类似的东西,但似乎scrapy导航严格基于xpath和css名称。

这就是 Scrapy 在这种情况下的使用方式吗?我可以做些什么来减少抓取过程的冗余?

这是我的第一个工作的爬虫蜘蛛,所以放轻松!

【问题讨论】:

    标签: python scrapy


    【解决方案1】:

    如果您只需要提取链接文本中带有特定子字符串的链接,您可以使用 LinkExtractor 和以下 XPath:

    LinkExtractor(restrict_xpaths='//a[contains(text(), "substring to find")]').extract_links(response)
    

    LinkExtractor 是在 Scrapy 中提取和处理链接的正确方法。

    文档:https://doc.scrapy.org/en/latest/topics/link-extractors.html

    【讨论】:

    • 谢谢,这正是我想要的
    猜你喜欢
    • 2011-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多