Scrapy爬取stackoverflow匹配多个标签的问题
Scrapy crawling stackoverflow questions matching multiple tags
我正在尝试 scrapy。我尝试了 http://doc.scrapy.org/en/1.0/intro/overview.html 页面中的示例代码。我尝试使用标签 'bigdata' 提取最近的问题。一切都很好。但是,当我尝试提取带有 'bigdata' 和 'python' 这两个标签的问题时,结果不正确,结果中只有 'bigdata' 标签的问题。但是在浏览器上,我对这两个标签的问题都正确。请在下面找到代码:
import scrapy
class WhosebugSpider(scrapy.Spider):
name = 'Whosebug'
start_urls = ['https://whosebug.com/questions/tagged/bigdata?page=1&sort=newest&pagesize=50']
def parse(self, response):
for href in response.css('.question-summary h3 a::attr(href)'):
full_url = response.urljoin(href.extract())
yield scrapy.Request(full_url, callback=self.parse_question)
def parse_question(self, response):
yield {
'title': response.css('h1 a::text').extract()[0],
'votes': response.css('.question .vote-count-post::text').extract()[0],
'body': response.css('.question .post-text').extract()[0],
'tags': response.css('.question .post-tag::text').extract(),
'link': response.url,
}
当我将 start_urls 更改为
start_urls = ['https://whosebug.com/questions/tagged/bigdata+python?page=1&sort=newest&pagesize=50']
结果包含只有 'bigdata' 标签的问题。如何仅使用这两个标签获取问题?
Edit:我认为发生的事情是 scrapy 正在从我提供的主页进入带有标签 'bigdata' 的页面,因为标签是指向主页面的链接该标签的页面。我如何编辑此代码以使 scrapy 不进入标签页面而只进入该页面中的问题?我尝试使用如下规则,但结果仍然不正确。
rules = (Rule(LinkExtractor(restrict_css='.question-summary h3 a::attr(href)'), callback='parse_question'),)
您拥有的 url(以及最初的 css 规则)是正确的;或者更简单地说:
start_urls = ['https://whosebug.com/questions/tagged/python+bigdata']
从 this 推断,这也适用:
start_urls = ['https://whosebug.com/questions/tagged/bigdata%20python']
但是,您 运行 遇到的问题是,Whosebug 似乎要求您 登录 才能访问多标签搜索功能。要看到这一点,只需退出您的 Whosebug 会话并在您的浏览器中尝试相同的 url。它会将您重定向到仅包含两个标签中第一个标签的结果页面。
TL;DR 获得多标签功能的唯一方法似乎是登录(通过会话 cookie 强制执行)
因此,当使用 scrapy
时,修复方法是在执行任何其他操作之前对会话(登录)进行身份验证,然后继续正常解析,一切正常。为此,您可以使用 InitSpider
而不是 Spider
并添加适当的登录方法。假设您直接使用 Whosebug 登录(而不是通过 Google 等),我能够像这样按预期工作:
import scrapy
import getpass
from scrapy.spiders.init import InitSpider
class WhosebugSpider(InitSpider):
name = 'Whosebug'
login_page = 'https://whosebug.com/users/login'
start_urls = ['https://whosebug.com/questions/tagged/bigdata+python']
def parse(self, response):
...
def parse_question(self, response):
...
def init_request(self):
return scrapy.Request(url=self.login_page, callback=self.login)
def login(self, response):
return scrapy.FormRequest.from_response(response,
formdata={'email': 'yourEmailHere@foobar.com',
'password': getpass.getpass()},
callback=self.check_login_response)
def check_login_response(self, response):
if "/users/logout" in response.body:
self.log("Successfully logged in")
return self.initialized()
else:
self.log("Failed login")
我正在尝试 scrapy。我尝试了 http://doc.scrapy.org/en/1.0/intro/overview.html 页面中的示例代码。我尝试使用标签 'bigdata' 提取最近的问题。一切都很好。但是,当我尝试提取带有 'bigdata' 和 'python' 这两个标签的问题时,结果不正确,结果中只有 'bigdata' 标签的问题。但是在浏览器上,我对这两个标签的问题都正确。请在下面找到代码:
import scrapy
class WhosebugSpider(scrapy.Spider):
name = 'Whosebug'
start_urls = ['https://whosebug.com/questions/tagged/bigdata?page=1&sort=newest&pagesize=50']
def parse(self, response):
for href in response.css('.question-summary h3 a::attr(href)'):
full_url = response.urljoin(href.extract())
yield scrapy.Request(full_url, callback=self.parse_question)
def parse_question(self, response):
yield {
'title': response.css('h1 a::text').extract()[0],
'votes': response.css('.question .vote-count-post::text').extract()[0],
'body': response.css('.question .post-text').extract()[0],
'tags': response.css('.question .post-tag::text').extract(),
'link': response.url,
}
当我将 start_urls 更改为
start_urls = ['https://whosebug.com/questions/tagged/bigdata+python?page=1&sort=newest&pagesize=50']
结果包含只有 'bigdata' 标签的问题。如何仅使用这两个标签获取问题?
Edit:我认为发生的事情是 scrapy 正在从我提供的主页进入带有标签 'bigdata' 的页面,因为标签是指向主页面的链接该标签的页面。我如何编辑此代码以使 scrapy 不进入标签页面而只进入该页面中的问题?我尝试使用如下规则,但结果仍然不正确。
rules = (Rule(LinkExtractor(restrict_css='.question-summary h3 a::attr(href)'), callback='parse_question'),)
您拥有的 url(以及最初的 css 规则)是正确的;或者更简单地说:
start_urls = ['https://whosebug.com/questions/tagged/python+bigdata']
从 this 推断,这也适用:
start_urls = ['https://whosebug.com/questions/tagged/bigdata%20python']
但是,您 运行 遇到的问题是,Whosebug 似乎要求您 登录 才能访问多标签搜索功能。要看到这一点,只需退出您的 Whosebug 会话并在您的浏览器中尝试相同的 url。它会将您重定向到仅包含两个标签中第一个标签的结果页面。
TL;DR 获得多标签功能的唯一方法似乎是登录(通过会话 cookie 强制执行)
因此,当使用 scrapy
时,修复方法是在执行任何其他操作之前对会话(登录)进行身份验证,然后继续正常解析,一切正常。为此,您可以使用 InitSpider
而不是 Spider
并添加适当的登录方法。假设您直接使用 Whosebug 登录(而不是通过 Google 等),我能够像这样按预期工作:
import scrapy
import getpass
from scrapy.spiders.init import InitSpider
class WhosebugSpider(InitSpider):
name = 'Whosebug'
login_page = 'https://whosebug.com/users/login'
start_urls = ['https://whosebug.com/questions/tagged/bigdata+python']
def parse(self, response):
...
def parse_question(self, response):
...
def init_request(self):
return scrapy.Request(url=self.login_page, callback=self.login)
def login(self, response):
return scrapy.FormRequest.from_response(response,
formdata={'email': 'yourEmailHere@foobar.com',
'password': getpass.getpass()},
callback=self.check_login_response)
def check_login_response(self, response):
if "/users/logout" in response.body:
self.log("Successfully logged in")
return self.initialized()
else:
self.log("Failed login")