【发布时间】: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 在这种情况下的使用方式吗?我可以做些什么来减少抓取过程的冗余?
这是我的第一个工作的爬虫蜘蛛,所以放轻松!
【问题讨论】: