在Scrapy docs中,有以下示例说明如何在Scrapy中使用经过身份验证的会话:
class LoginSpider(BaseSpider):
name = 'example.com'
start_urls = ['http://www.example.com/users/login.php']
def parse(self, response):
return [FormRequest.from_response(response,
formdata={'username': 'john', 'password': 'secret'},
callback=self.after_login)]
def after_login(self, response):
# check login succeed before going on
if "authentication failed" in response.body:
self.log("Login failed", level=log.ERROR)
return
# continue scraping with authenticated session...
我已经做好了,很好。但是 我的问题是 :continue scraping with authenticated session
正如他们在最后一行的评论中所说,您需要做什么?
在上面的代码中,FormRequest
用于进行身份验证的将该after_login
函数设置为其回调。这意味着该after_login
函数将被调用并传递登录尝试得到的页面作为响应。
然后,通过在页面中搜索特定的字符串(在本例中为)来检查您是否成功登录"authentication failed"
。如果找到它,蜘蛛就会结束。
现在,一旦蜘蛛走了那么远,它就知道它已经成功通过了身份验证,您就可以开始产生新的请求和/或抓取数据了。因此,在这种情况下:
from scrapy.selector import HtmlXPathSelector
from scrapy.http import Request
# ...
def after_login(self, response):
# check login succeed before going on
if "authentication failed" in response.body:
self.log("Login failed", level=log.ERROR)
return
# We've successfully authenticated, let's have some fun!
else:
return Request(url="http://www.example.com/tastypage/",
callback=self.parse_tastypage)
def parse_tastypage(self, response):
hxs = HtmlXPathSelector(response)
yum = hxs.select('//img')
# etc.
如果您
在此处查看
,则有一个蜘蛛示例,该示例会在刮刮之前进行身份验证。
在这种情况下,它将处理parse
函数中的内容(任何请求的默认回调)。
def parse(self, response):
hxs = HtmlXPathSelector(response)
if hxs.select("//form[@id='UsernameLoginForm_LoginForm']"):
return self.login(response)
else:
return self.get_section_links(response)
因此,无论何时发出请求,都会检查响应中是否存在登录表单。如果存在,那么我们知道我们需要登录,所以我们调用相关的函数,如果不存在,则调用负责从响应中抓取数据的函数。
我希望这很清楚,请随时询问您还有其他问题!
编辑:
好的,所以您要做的不只是产生单个请求并将其抓取。您想点击链接。
为此,您需要做的就是从页面上抓取相关链接,并使用这些URL生成请求。例如:
def parse_page(self, response):
""" Scrape useful stuff from page, and spawn new requests
"""
hxs = HtmlXPathSelector(response)
images = hxs.select('//img')
# .. do something with them
links = hxs.select('//a/@href')
# Yield a new request for each link we found
for link in links:
yield Request(url=link, callback=self.parse_page)
如您所见,它为页面上的每个URL生成了一个新请求,并且这些请求中的每一个都将使用其响应调用此相同的函数,因此我们正在进行一些递归的抓取。
我上面写的只是一个例子。如果要“抓取”页面,则应调查CrawlSpider
而不是手动处理。
问题内容: 我知道这是电气工程惯例,但是我仍然想知道为什么选择Python。我不知道其他具有复数文字的编程语言,因此我没有什么可比较的,但是有人知道有使用i的语言吗? 问题答案: 如您所料,这似乎是因为Python遵循电气工程惯例。这是Python Bug跟踪器Issue10562的交换: BoštjanMejak :在Python中,字母“ j”表示虚数单位。如果我们在这方面遵循数学并以“ i”
我碰巧知道,在下面的表达式中,使用将导致无限流,将始终为0。我之所以困惑是因为我认为返回的值没有被使用,即便如此,它也不应该中断之后的增量。
问题内容: 我在一个开始从事的项目中遇到了这段代码。原始开发人员不再可用,我对此一无所知: 产生值为。这是如何运作的? 什么是运算符? 什么是运算符? 什么是运算符? 什么是运算符? 问题答案: 什么是运算符? 那是两个运算符,一个是赋值运算符,一个是一元加号,它什么都不做。 您是否输入错了并表示compund赋值运算符? 什么是运算符? 还有两个运算符,一个为后递增,一个为加法(根据最大划分规则
问题内容: 也许对编译器进行优化后并不重要,但是在C / C ++中,我看到大多数人以以下形式进行for循环: 使用postfix 完成增量操作。我得到了两种形式之间的区别。i 返回i的当前值,但是在安静时将1加到i。++ i首先将1加到i,然后返回新值(比i大1)。 我认为i 需要做更多的工作,因为除了下一个值外,还需要存储一个前一个值:推 (&i)进行堆栈(或加载至寄存器);递增(&i)。与
问题内容: 许多人和作者建议我们使用列表而不是数组。 它背后的原因是什么? 问题答案: 通常,您应该更喜欢为工作选择正确的数据结构。您需要了解手头的任务以及所有不同的选项,以及它们如何在迭代,搜索,添加,删除和插入数据方面进行比较。通常,您需要了解数据结构如何访问和操作内存,并根据对应用程序的预期使用来选择最佳的数据结构。 显然,它并不总是很明确。但是您可以了解不同数据结构的理想选择。 例如,纯静
问题内容: 今天,我遇到了该方法,该方法在字典中给定键,然后返回关联的值。 此功能用于什么目的?如果我想找到与字典中的键相关联的值,我可以这样做,并且它返回相同的内容: 问题答案: 如果密钥丢失,它允许您提供默认值: 返回(无论您选择的是什么),而 会提出一个。 如果省略,则为,这样 返回就像