用scrapy导航hrefs的最佳实践

时间:2017-01-20 03:08:58

标签: python scrapy

我正在构建一个从网站下载csv文件的网络剪贴簿。我必须登录多个用户帐户才能下载所有文件。我还必须浏览几个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是如何在这种情况下使用的?我能做些什么来减少刮削过程的冗余吗?

这是我第一次使用scrapy蜘蛛,所以对我来说很容易!

1 个答案:

答案 0 :(得分: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