如何使用scrapy抓取Ask引擎搜索结果?
How to scrape Ask engine search results using scrapy?
我创建了一个蜘蛛来从一组用户定义的关键字中抓取 Ask 搜索结果。但是,每当我 运行 命令 scrapy crawl pageSearch -o test.json
这会为我创建一个空的 test.json 文件时,我不知道为什么。为了创建这个 api,我受到了开发人员 page that showed how to scrape google SERPs and also the tutorial from the official scrapy documentation. Here is a git of what I get from the command line 的启发。我从堆栈溢出问题中搜索了解决方案,但没有成功。我从以下命令提示行相信:'scrapy.spidermiddlewares.httperror.HttpErrorMiddleware'
这是一个 http 错误,但在互联网上搜索后它不是,根据我的终端,我的机器人 运行 成功并且 url 地址我在代码中指定的 scraping 发生位置是有效的。就个人而言,我没有看到我的错误,所以我迷路了。这是我的代码:
import scrapy
import json
import datetime
class PagesearchSpider(scrapy.Spider):
name = 'pageSearch'
def start_requests(self):
queries = [ 'love']
for query in queries:
url = 'https://www.ask.com/web?q='+query
yield scrapy.Request(url, callback=self.parse, meta={'pos': 0})
def parse(self, response):
print(response.text)
di = json.loads(response.text)
pos = response.meta['pos']
dt = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
for result in di['organic_results']:
title = result['a.PartialSearchResults-item-title-link.result-link']
snippet = result['p.PartialSearchResults-item-abstract']
link = result['div.PartialSearchResults-item-url']
item = {'title': title, 'snippet': snippet, 'link': link, 'position': pos, 'date': dt}
pos += 1
yield item
next_page = di['pagination']['nextPageUrl']
if next_page:
yield scrapy.Request(next_page, callback=self.parse, meta={'pos': pos})
#scrapy crawl pageSearch -o test.json
我用的是Windows10。另外,还请大家帮忙,谢谢!
我发现了两个问题:
第一个:
在你的输出中你可以看到
[scrapy.downloadermiddlewares.robotstxt] DEBUG: Forbidden by robots.txt: <GET https://www.ask.com/web?q=love>
这意味着它读取https://www.ask.com/robots.txt并且有规则
User-agent: *
Disallow: /web
scrapy 尊重它并跳过 url https://www.ask.com/web?q=love
您必须在 settings.py 中设置 ROBOTTXT_OBEY = False
才能将其关闭。
Scrapy 文档:ROBOTTXT_OBEY
第二个:
您使用 di = json.loads(response.text)
,这意味着您需要 JSON
数据,但此页面发送 HTML
,您必须使用函数 response.css(...)
、response.xpath(...)
和 .get()
、.attrib.get(...)
、等等
Scrapy 文档:Selectors
工作代码:
您可以将所有代码放在一个文件 script.py
和 运行 中作为 python script.py
而无需创建项目。它还会自动将结果保存在 test.json
中,而无需使用 -o test.json
import scrapy
import datetime
class PagesearchSpider(scrapy.Spider):
name = 'pageSearch'
def start_requests(self):
queries = [ 'love']
for query in queries:
url = 'https://www.ask.com/web?q='+query
yield scrapy.Request(url, callback=self.parse, meta={'pos': 0})
def parse(self, response):
print('url:', response.url)
start_pos = response.meta['pos']
print('start pos:', start_pos)
dt = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
items = response.css('div.PartialSearchResults-item')
for pos, result in enumerate(items, start_pos+1):
yield {
'title': result.css('a.PartialSearchResults-item-title-link.result-link::text').get().strip(),
'snippet': result.css('p.PartialSearchResults-item-abstract::text').get().strip(),
'link': result.css('a.PartialSearchResults-item-title-link.result-link').attrib.get('href'),
'position': pos,
'date': dt,
}
# --- after loop ---
next_page = response.css('.PartialWebPagination-next a')
if next_page:
url = next_page.attrib.get('href')
print('next_page:', url) # relative URL
# use `follow()` to add `https://www.ask.com/` to URL and create absolute URL
yield response.follow(url, callback=self.parse, meta={'pos': pos+1})
# --- run without project, and save in file ---
from scrapy.crawler import CrawlerProcess
c = CrawlerProcess({
#'USER_AGENT': 'Mozilla/5.0',
# save in file CSV, JSON or XML
'FEEDS': {'test.json': {'format': 'json'}},
#'ROBOTSTXT_OBEY': True, # this stop scraping
})
c.crawl(PagesearchSpider)
c.start()
我创建了一个蜘蛛来从一组用户定义的关键字中抓取 Ask 搜索结果。但是,每当我 运行 命令 scrapy crawl pageSearch -o test.json
这会为我创建一个空的 test.json 文件时,我不知道为什么。为了创建这个 api,我受到了开发人员 page that showed how to scrape google SERPs and also the tutorial from the official scrapy documentation. Here is a git of what I get from the command line 的启发。我从堆栈溢出问题中搜索了解决方案,但没有成功。我从以下命令提示行相信:'scrapy.spidermiddlewares.httperror.HttpErrorMiddleware'
这是一个 http 错误,但在互联网上搜索后它不是,根据我的终端,我的机器人 运行 成功并且 url 地址我在代码中指定的 scraping 发生位置是有效的。就个人而言,我没有看到我的错误,所以我迷路了。这是我的代码:
import scrapy
import json
import datetime
class PagesearchSpider(scrapy.Spider):
name = 'pageSearch'
def start_requests(self):
queries = [ 'love']
for query in queries:
url = 'https://www.ask.com/web?q='+query
yield scrapy.Request(url, callback=self.parse, meta={'pos': 0})
def parse(self, response):
print(response.text)
di = json.loads(response.text)
pos = response.meta['pos']
dt = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
for result in di['organic_results']:
title = result['a.PartialSearchResults-item-title-link.result-link']
snippet = result['p.PartialSearchResults-item-abstract']
link = result['div.PartialSearchResults-item-url']
item = {'title': title, 'snippet': snippet, 'link': link, 'position': pos, 'date': dt}
pos += 1
yield item
next_page = di['pagination']['nextPageUrl']
if next_page:
yield scrapy.Request(next_page, callback=self.parse, meta={'pos': pos})
#scrapy crawl pageSearch -o test.json
我用的是Windows10。另外,还请大家帮忙,谢谢!
我发现了两个问题:
第一个:
在你的输出中你可以看到
[scrapy.downloadermiddlewares.robotstxt] DEBUG: Forbidden by robots.txt: <GET https://www.ask.com/web?q=love>
这意味着它读取https://www.ask.com/robots.txt并且有规则
User-agent: *
Disallow: /web
scrapy 尊重它并跳过 url https://www.ask.com/web?q=love
您必须在 settings.py 中设置 ROBOTTXT_OBEY = False
才能将其关闭。
Scrapy 文档:ROBOTTXT_OBEY
第二个:
您使用 di = json.loads(response.text)
,这意味着您需要 JSON
数据,但此页面发送 HTML
,您必须使用函数 response.css(...)
、response.xpath(...)
和 .get()
、.attrib.get(...)
、等等
Scrapy 文档:Selectors
工作代码:
您可以将所有代码放在一个文件 script.py
和 运行 中作为 python script.py
而无需创建项目。它还会自动将结果保存在 test.json
中,而无需使用 -o test.json
import scrapy
import datetime
class PagesearchSpider(scrapy.Spider):
name = 'pageSearch'
def start_requests(self):
queries = [ 'love']
for query in queries:
url = 'https://www.ask.com/web?q='+query
yield scrapy.Request(url, callback=self.parse, meta={'pos': 0})
def parse(self, response):
print('url:', response.url)
start_pos = response.meta['pos']
print('start pos:', start_pos)
dt = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
items = response.css('div.PartialSearchResults-item')
for pos, result in enumerate(items, start_pos+1):
yield {
'title': result.css('a.PartialSearchResults-item-title-link.result-link::text').get().strip(),
'snippet': result.css('p.PartialSearchResults-item-abstract::text').get().strip(),
'link': result.css('a.PartialSearchResults-item-title-link.result-link').attrib.get('href'),
'position': pos,
'date': dt,
}
# --- after loop ---
next_page = response.css('.PartialWebPagination-next a')
if next_page:
url = next_page.attrib.get('href')
print('next_page:', url) # relative URL
# use `follow()` to add `https://www.ask.com/` to URL and create absolute URL
yield response.follow(url, callback=self.parse, meta={'pos': pos+1})
# --- run without project, and save in file ---
from scrapy.crawler import CrawlerProcess
c = CrawlerProcess({
#'USER_AGENT': 'Mozilla/5.0',
# save in file CSV, JSON or XML
'FEEDS': {'test.json': {'format': 'json'}},
#'ROBOTSTXT_OBEY': True, # this stop scraping
})
c.crawl(PagesearchSpider)
c.start()