不积跬步,无以至千里;不积小流,无以成江海。

Dean's blog

  • Join Us on Facebook!
  • Follow Us on Twitter!
  • LinkedIn
  • Subcribe to Our RSS Feed

Scrapy网页抓取不全的几个检查点

最近在学习Scrapy,拿本网站作为小白鼠练手,发现网页有些数据抓不取。经过不断踩坑,发现可能导致网页抓取不全的原因,可能有以下几种:

1、robots协议导致

robots协议也叫robots.txt(统一小写)是一种存放于网站根目录下的ASCII编码的文本文件,它通常告诉网络搜索引擎的漫游器(又称网络蜘蛛),此网站中的哪些内容是不应被搜索引擎的漫游器获取的,哪些是可以被漫游器获取的。因为一些系统中的URL是大小写敏感的,所以robots.txt的文件名应统一为小写。robots.txt应放置于网站的根目录下。如果想单独定义搜索引擎的漫游器访问子目录时的行为,那么可以将自定的设置合并到根目录下的robots.txt,或者使用robots元数据(Metadata,又称元数据)。

摘自百度百科

robots是网站用来告诉蜘蛛哪些网页可爬取,哪些不可爬取的一种约定俗成的协议。例如某宝的robots除了开放几个爬虫对几个目录的爬取外,其它的都拒绝了。默认的,Scrapy也是遵守这个协议的,如果链接在禁止范围内,就会自动跳过。所以如果需要,可以调整配置让Scrapy是否遵守这个协议。设置为False可以爬取更多的内容。配置项在settings.py:

# Obey robots.txt rules
ROBOTSTXT_OBEY = True

2、被LinkExtractor忽略

如果对Scrapy的默认行为不理解,这个会是一个比较隐秘的,容易造成困惑的点。例如,使用scrapy genspider -t crawl .....使用crawl创建的爬虫后,如果以下的方式定义Rule,期望可以爬取样式表和更多的网页:

rules = (
    Rule(LinkExtractor(allow=r'\.css', tags='link' attrs='href'), callback='parse_css', follow=False),
    Rule(LinkExtractor(allow=r'.+'), callback='parse_page', follow=False),
)

但是运行后,会发现,第一个Rule压根就不会抓取任何的样式表,第二个也会忽略掉一些链接。造成这个的原因,需要了解下LinkExtractor的参数(LinkExtractorLxmlLinkExtractor的一个别名):

class scrapy.linkextractors.lxmlhtml.LxmlLinkExtractor(allow=(), deny=(), allow_domains=(), deny_domains=(), deny_extensions=None, restrict_xpaths=(), restrict_css=(), tags=('a', 'area'), attrs=('href', ), canonicalize=True, unique=True, process_value=None)

allow(正则表达式(或的列表)) - 一个单一的正则表达式(或正则表达式列表),(绝对)urls必须匹配才能提取。如果没有给出(或为空),它将匹配所有链接。
deny(正则表达式或正则表达式列表) - 一个正则表达式(或正则表达式列表),(绝对)urls必须匹配才能排除(即不提取)。它优先于allow参数。如果没有给出(或为空),它不会排除任何链接。
allow_domains(str或list) - 单个值或包含将被考虑用于提取链接的域的字符串列表
deny_domains(str或list) - 单个值或包含不会被考虑用于提取链接的域的字符串列表
deny_extensions(list) - 包含在提取链接时应该忽略的扩展的单个值或字符串列表。如果没有给出,它将默认为IGNORED_EXTENSIONS在scrapy.linkextractors包中定义的 列表 。
restrict_xpaths(str或list) - 是一个XPath(或XPath的列表),它定义响应中应从中提取链接的区域。如果给出,只有那些XPath选择的文本将被扫描链接。参见下面的例子。
restrict_css(str或list) - 一个CSS选择器(或选择器列表),用于定义响应中应提取链接的区域。有相同的行为restrict_xpaths。
标签(str或list) - 标签或在提取链接时要考虑的标签列表。默认为。('a', 'area')
attrs(list) - 在查找要提取的链接时应该考虑的属性或属性列表(仅适用于参数中指定的那些标签tags )。默认为('href',)
canonicalize(boolean) - 规范化每个提取的url(使用w3lib.url.canonicalize_url)。默认为True。
unique(boolean) - 是否应对提取的链接应用重复过滤。
process_value(callable) -
接收从标签提取的每个值和扫描的属性并且可以修改值并返回新值的函数,或者返回None以完全忽略链接。如果没有给出,process_value默认为。lambda x: x

出处简书

其中deny_extensions的值为:

# common file extensions that are not followed if they occur in links
IGNORED_EXTENSIONS = [
    # images
    'mng', 'pct', 'bmp', 'gif', 'jpg', 'jpeg', 'png', 'pst', 'psp', 'tif',
    'tiff', 'ai', 'drw', 'dxf', 'eps', 'ps', 'svg',

    # audio
    'mp3', 'wma', 'ogg', 'wav', 'ra', 'aac', 'mid', 'au', 'aiff',

    # video
    '3gp', 'asf', 'asx', 'avi', 'mov', 'mp4', 'mpg', 'qt', 'rm', 'swf', 'wmv',
    'm4a', 'm4v', 'flv',

    # office suites
    'xls', 'xlsx', 'ppt', 'pptx', 'pps', 'doc', 'docx', 'odt', 'ods', 'odg',
    'odp',

    # other
    'css', 'pdf', 'exe', 'bin', 'rss', 'zip', 'rar',
]

所以,如果想抓取样式表,可以这样定义Rute:

rules = (
    Rule(LinkExtractor(allow=r'\.css', tags='link' attrs='href', deny_extensions=['abc']), callback='parse_css', follow=False),
)

将deny_extensions定义为一个不包含.css后缀的即可。

不允许评论
粤ICP备17049187号-1