我只提到我在发布这个问题之前提到的一些问题(在发布这个问题之前,我目前没有链接到我提到过的所有问题) - :
我可以完全运行此代码,如果我没有传递参数并要求用户从BBSpider类输入(没有主函数 - 在name ="dmoz"行下方),或者将它们作为预定义(即静态)参数.
我的代码在这里.
我基本上试图从Python脚本执行Scrapy蜘蛛而不需要任何其他文件(甚至是设置文件).这就是为什么我在代码本身内部也指定了设置.
这是我执行此脚本时的输出 - :
http://bigbasket.com/ps/?q=apple
2015-06-26 12:12:34 [scrapy] INFO: Scrapy 1.0.0 started (bot: scrapybot)
2015-06-26 12:12:34 [scrapy] INFO: Optional features available: ssl, http11
2015-06-26 12:12:34 [scrapy] INFO: Overridden settings: {}
2015-06-26 12:12:35 [scrapy] INFO: Enabled extensions: CloseSpider, TelnetConsole, LogStats, CoreStats, SpiderState
None
2015-06-26 12:12:35 [scrapy] INFO: Enabled downloader middlewares: HttpAuthMiddleware, DownloadTimeoutMiddleware, UserAgentMiddleware, RetryMiddleware, DefaultHeadersMiddleware, MetaRefreshMiddleware, HttpCompressionMiddleware, RedirectMiddleware, CookiesMiddleware, ChunkedTransferMiddleware, DownloaderStats
2015-06-26 12:12:35 [scrapy] INFO: Enabled spider middlewares: HttpErrorMiddleware, …Run Code Online (Sandbox Code Playgroud) 我有Scrapy(版本1.0.3)蜘蛛,其中我从网页中提取了一些数据,我也下载了文件,像这样(简化):
def extract_data(self, response):
title = response.xpath('//html/head/title/text()').extract()[0].strip()
my_item = MyItem()
my_item['title'] = title
file_url = response.xpath('...get url of file...')
file_urls = [file_url] # here there can be more urls, so I'm storing like a list
fi = FileItem()
fi['file_urls'] = file_urls
yield my_item
yield fi
Run Code Online (Sandbox Code Playgroud)
在pipelines.py中我只是重写FilePipeline来更改文件的名称:
from scrapy.pipelines.files import FilesPipeline
class CustomFilesPipeline(FilesPipeline):
def file_path(self, request, response=None, info=None):
filename = format_filename(request.url)
return filename
Run Code Online (Sandbox Code Playgroud)
在items.py我有:
class MyItem(scrapy.Item):
title = scrapy.Field()
class FileItem(scrapy.Item):
file_urls = scrapy.Field()
files = scrapy.Field()
Run Code Online (Sandbox Code Playgroud)
在settings.py我有:
ITEM_PIPELINES = { …Run Code Online (Sandbox Code Playgroud) 我有以下Django模型。我不确定使用scrapy管道在Spider中扫描到Django中的数据库时,保存这些相互关联的对象的最佳方法是什么。似乎刮擦的管道仅用于处理一种“种类”的物料
class Parent(models.Model):
field1 = CharField()
class ParentX(models.Model):
field2 = CharField()
parent = models.OneToOneField(Parent, related_name = 'extra_properties')
class Child(models.Model):
field3 = CharField()
parent = models.ForeignKey(Parent, related_name='childs')
Run Code Online (Sandbox Code Playgroud)
# uses DjangoItem https://github.com/scrapy-plugins/scrapy-djangoitem
class ParentItem(DjangoItem):
django_model = Parent
class ParentXItem(DjangoItem):
django_model = ParentX
class ChildItem(DjangoItem):
django_model = Child
Run Code Online (Sandbox Code Playgroud)
class MySpider(scrapy.Spider):
name = "myspider"
allowed_domains = ["abc.com"]
start_urls = [
"http://www.example.com", # this page has ids of several Parent objects whose full details are in their individual pages
]
def parse(self, …Run Code Online (Sandbox Code Playgroud) 我试图编写一个通用的“ Master”蜘蛛,将其与执行期间动态插入的“ start_urls”和“ allowed_domains”一起使用。(最终,我将这些存储在数据库中,然后将其拉出,然后用于初始化和抓取每个数据库条目的新蜘蛛。)
目前,我有两个文件:
为了编写这两个文件,我引用了以下内容:
我考虑了scrapyD,但我认为它不是我想要的...
这是我写的:
MySpider.py-
import scrapy
class BlackSpider(scrapy.Spider):
name = 'Black1'
def __init__(self, allowed_domains=[], start_urls=[], *args, **kwargs):
super(BlackSpider, self).__init__(*args, **kwargs)
self.start_urls = start_urls
self.allowed_domains = allowed_domains
#For Testing:
print start_urls
print self.start_urls
print allowed_domains
print self.allowed_domains
def parse(self, response):
#############################
# Insert my parse code here #
#############################
return items
Run Code Online (Sandbox Code Playgroud)
RunSpider.py-
import scrapy
from scrapy.crawler import CrawlerProcess
from MySpider import BlackSpider
#Set my …Run Code Online (Sandbox Code Playgroud) 我正在使用Splash 2.0.2 + Scrapy 1.0.5 + Scrapyjs 0.1.1,我仍然无法通过点击呈现JavaScript.以下是一个示例网址https://olx.pt/anuncio/loja-nova-com-250m2-garagem-em-box-fechada-para-arrumos-IDyTzAT.html#c49d3d94cf
我仍然没有提供电话号码的页面:
class OlxSpider(scrapy.Spider):
name = "olx"
rotate_user_agent = True
allowed_domains = ["olx.pt"]
start_urls = [
"https://olx.pt/imoveis/"
]
def parse(self, response):
script = """
function main(splash)
splash:go(splash.args.url)
splash:runjs('document.getElementById("contact_methods").getElementsByTagName("span")[1].click();')
splash:wait(0.5)
return splash:html()
end
"""
for href in response.css('.link.linkWithHash.detailsLink::attr(href)'):
url = response.urljoin(href.extract())
yield scrapy.Request(url, callback=self.parse_house_contents, meta={
'splash': {
'args': {'lua_source': script},
'endpoint': 'execute',
}
})
for next_page in response.css('.pager .br3.brc8::attr(href)'):
url = response.urljoin(next_page.extract())
yield scrapy.Request(url, self.parse)
def parse_house_contents(self, response):
import ipdb;ipdb.set_trace()
Run Code Online (Sandbox Code Playgroud)
我怎么能让这个工作?
这是一个简单的scrapy蜘蛛
import scrapy
class ExampleSpider(scrapy.Spider):
name = "dmoz"
allowed_domains = ["https://www.dmoz.org"]
start_urls = ('https://www.dmoz.org/')
def parse(self,response):
yield scrapy.Request(self.start_urls[0],callback=self.parse2)
def parse2(self, response):
print(response.url)
Run Code Online (Sandbox Code Playgroud)
当您运行该程序时,parse2方法不起作用,它不会打印response.url.然后我在下面的帖子中找到了解决方案.
为什么我的第二个请求没有被我的scrapy蜘蛛的parse方法调用
它只是我需要在请求方法中添加dont_filter = True作为参数以使parse2函数工作.
yield scrapy.Request(self.start_urls[0],callback=self.parse2,dont_filter=True)
Run Code Online (Sandbox Code Playgroud)
但是在scrapy文档和许多youtube教程中给出的示例中,他们从未在scrapy.Request方法中使用dont_filter = True参数,但仍然可以使用其第二个解析函数.
看看这个
def parse_page1(self, response):
return scrapy.Request("http://www.example.com/some_page.html",
callback=self.parse_page2)
def parse_page2(self, response):
# this would log http://www.example.com/some_page.html
self.logger.info("Visited %s", response.url)
Run Code Online (Sandbox Code Playgroud)
除非添加dont_filter = True,为什么我的蜘蛛不能工作?我究竟做错了什么 ?在我的第一个例子中,我的蜘蛛过滤了哪些重复的链接?
PS我可以在上面发布的QA帖子中解决这个问题,但我不能发表评论,除非我有50个声望(可怜的我!!)
我只需要了解如何检测scrapy是否已保存以及蜘蛛中的项目?我正在从网站上获取项目,之后我正在获取该项目的评论.所以首先我必须保存项目,之后我会保存评论.但是当我在编写代码之后编写代码时,它会给我这个错误.
save() prohibited to prevent data loss due to unsaved related object ''.
这是我的代码
def parseProductComments(self, response):
name = response.css('h1.product-name::text').extract_first()
price = response.css('span[id=offering-price] > span::text').extract_first()
node = response.xpath("//script[contains(text(),'var utagData = ')]/text()")
data = node.re('= (\{.+\})')[0] #data = xpath.re(" = (\{.+\})")
data = json.loads(data)
barcode = data['product_barcode']
objectImages = []
for imageThumDiv in response.css('div[id=productThumbnailsCarousel]'):
images = imageThumDiv.xpath('img/@data-src').extract()
for image in images:
imageQuality = image.replace('/80/', '/500/')
objectImages.append(imageQuality)
company = Company.objects.get(pk=3)
comments = []
item = ProductItem(name=name, price=price, barcode=barcode, file_urls=objectImages, product_url=response.url,product_company=company, comments = …Run Code Online (Sandbox Code Playgroud) 我试图通过脚本以编程方式调用蜘蛛.我无法使用CrawlerProcess通过构造函数覆盖设置.让我用默认的蜘蛛来说明这一点,用于从官方scrapy站点抓取引号(官方scrapy引用示例蜘蛛的最后一个代码片段).
class QuotesSpider(Spider):
name = "quotes"
def __init__(self, somestring, *args, **kwargs):
super(QuotesSpider, self).__init__(*args, **kwargs)
self.somestring = somestring
self.custom_settings = kwargs
def start_requests(self):
urls = [
'http://quotes.toscrape.com/page/1/',
'http://quotes.toscrape.com/page/2/',
]
for url in urls:
yield Request(url=url, callback=self.parse)
def parse(self, response):
for quote in response.css('div.quote'):
yield {
'text': quote.css('span.text::text').extract_first(),
'author': quote.css('small.author::text').extract_first(),
'tags': quote.css('div.tags a.tag::text').extract(),
}
Run Code Online (Sandbox Code Playgroud)
这是我尝试运行引号蜘蛛的脚本
from scrapy.crawler import CrawlerProcess
from scrapy.utils.project import get_project_settings
from scrapy.settings import Settings
def main():
proc = CrawlerProcess(get_project_settings())
custom_settings_spider = \
{
'FEED_URI': 'quotes.csv',
'LOG_FILE': 'quotes.log' …Run Code Online (Sandbox Code Playgroud) 我正在用 Scrapy 运行一个蜘蛛,但在它完成爬行后,它似乎无法终止。日志统计只是递归地报告它正在抓取 0 页/分钟。当我尝试使用 Ctrl-C 退出时,它无法正常关闭,我必须再次使用 Ctrl-C 强制退出。任何线索发生了什么?
完成刮擦后,我只是得到这样的输出:
2017-08-24 11:13:45 [scrapy.extensions.logstats] 信息:抓取 60 页(以 0 页/分钟),抓取 54 个项目(以 0 项/分钟)
2017-08-24 11:14:45 [scrapy.extensions.logstats] 信息:抓取 60 页(以 0 页/分钟),抓取 54 个项目(以 0 项/分钟)
2017-08-24 11:15:45 [scrapy.extensions.logstats] 信息:抓取 60 页(以 0 页/分钟),抓取 54 个项目(以 0 项/分钟)
2017-08-24 11:16:45 [scrapy.extensions.logstats] 信息:抓取 60 页(以 0 页/分钟),抓取 54 个项目(以 0 项/分钟)
2017-08-24 11:17:45 [scrapy.extensions.logstats] 信息:抓取 60 页(以 0 页/分钟),抓取 54 个项目(以 0 项/分钟)
2017-08-24 11:18:45 [scrapy.extensions.logstats] 信息:抓取 60 页(以 0 页/分钟),抓取 54 个项目(以 …
是否可以使用 Scrapy 生成网站的站点地图,包括每个页面的 URL 及其级别/深度(我需要从主页遵循的链接数量)?站点地图的格式不必是 XML,它只是关于信息。此外,我想保存被抓取页面的完整 HTML 源代码以供进一步分析,而不是仅从中抓取某些元素。
有使用 Scrapy 经验的人能否告诉我这是否是 Scrapy 可能/合理的场景,并给我一些有关如何查找说明的提示?到目前为止,我只能找到更复杂的场景,但没有解决这个看似简单的问题的方法。
经验丰富的网络爬虫的插件:鉴于它是可能的,你认为 Scrapy 甚至是合适的工具吗?或者使用请求等库编写自己的爬虫会更容易吗?
scrapy ×10
scrapy-spider ×10
python ×8
web-scraping ×4
django ×2
arguments ×1
bots ×1
python-3.x ×1
scrapinghub ×1
web-crawler ×1