我有一个网站,我想找一个包含职位空缺信息的网页。通常只有一页有这样的信息。所以我开始抓取网站,我设法让所有网页达到一定的深度。有用。但他们多次重复。而不是说45页我得到1000页。我知道原因。原因是每次我打电话给我的"解析"功能,它解析某个网页上的所有网页。因此,当我来到一个新的网页时,它会抓取所有网页,其中一些网页之前已被抓取过。
1)我试图制作" items = []"列出解析函数但我得到一些全局错误。我不知道如何获取唯一网页列表。当我有一个,我将能够通过简单的URL解析选择正确的。 2)我也尝试过"请求"和"退货"在"解析"函数,但我得到语法错误:返回内部生成器。
我正在使用DEPTH_LIMIT。我真的需要使用规则吗?
代码:
import scrapy, urlparse, os
from scrapy.spiders import Rule
from scrapy.linkextractors import LinkExtractor
from tutorial.items import JobItem
from scrapy.utils.response import get_base_url
from scrapy.http import Request
from urlparse import urljoin
from datetime import datetime
class JobSpider(scrapy.Spider):
name = "jobs"
allowed_domains = ["www.gen-i.si"]
start_urls = ["http://www.gen-i.si"]
def parse(self, response):
response.selector.remove_namespaces() #
urls = response.xpath('//@href').extract()#choose all "href", either new websites either webpages on our website
items = []
base_url = get_base_url(response) #base url
for url in urls:
#we need only webpages, so we remove all websites and urls with strange characters
if (url[0:4] != "http") and not any(x in url for x in ['%', ':', '?', '&']):
item = JobItem()
absolute_url = urlparse.urljoin(base_url,url)
item["link"] = absolute_url
if item not in items:
items.append(item)
yield item
yield Request(absolute_url, callback = self.parse)
#return items
答案 0 :(得分:0)
您将item
(新实例化的对象)附加到列表items
。由于item
始终是新的JobItem()
对象,因此它不会存在于您的列表items
中。
举例说明:
>>> class MyItem(object):
... pass
...
>>> a = MyItem()
>>> b = MyItem()
>>> a.url = "abc"
>>> b.url = "abc"
>>> a == b
False
仅仅因为他们有一个相同的属性,并不代表他们是同一个对象。
即使这有效,但每次调用解析时都会重置列表items
(即针对每个请求),因此您永远不会删除重复项。
相反,您可以更好地检查absolute_url
本身,并将列表放在蜘蛛级别:
class JobSpider(scrapy.Spider):
name = "jobs"
allowed_domains = ["www.gen-i.si"]
start_urls = ["http://www.gen-i.si"]
all_urls = []
def parse(self, response):
# remove "items = []"
...
for url in urls:
if (url[0:4] != "http") and not any(x in url for x in ['%', ':', '?', '&']):
absolute_url = urlparse.urljoin(base_url, url)
if absolute_url not in self.all_urls:
self.all_urls.append(absolute_url)
item = JobItem()
item['link'] = absolute_url
yield item
yield Request(absolute_url, callback = self.parse)
但是,通过创建Dupefilter
(see here for more information)可以更好地满足此功能。另外,我同意@RodrigoNey,CrawlSpider
可能会更好地满足您的目的,并且从长远来看更易于维护。
答案 1 :(得分:0)
我正在使用一个Web爬网程序,最终列出了需要爬网的链接列表,然后我们去了那里,就将其从该列表中删除并添加到了爬网列表中。那么您可以使用not in
搜索来添加/删除/等。