scrapy抓取所有网站域名
需求分析
从一个门户网站出发,试图爬取该门户网站所有链接,如此递归下去,发现新域名则保存起来,每个域名网站只爬取一次。有了这些数据在通过外部DNS获得IP,就可以自己搭建DNS服务器了
创建项目
创建一个项目,名叫crawl_all_domainname
scrapy startproject crawl_all_domainname
创建爬虫脚本domain.py, 从han123.com开始爬行
cd crawl_all_domainname/crawl_all_domainname crawl_all_domainname>scrapy genspider domain hao123.com
修改配置文件,忽略robots.txt
ROBOTSTXT_OBEY = False
代码实现
# -*- coding: utf-8 -*- import scrapy from urllib import parse import re already_crawl_dn=[] class DomainSpider(scrapy.Spider): name = 'domain' start_urls = ['http://hao123.com/'] def parse(self, response): #将已爬取的域名存入列表already_crawl domain = parse.urlparse(response._url).netloc.lstrip('www.') already_crawl_dn.append(domain) print('Crawl %s Done' % domain) #1.提取html页面中所有a标签中的href属性 #2.提取有效url(http://www...或https://www...) #3.将url转化为域名,在用set去重 dns = set([parse.urlparse(url).netloc.lstrip('www.') for url in response.css('a::attr(href)').getall() if re.fullmatch('(https|http)://www.*', url)]) #4.提取urls中没有爬取过的url, dns = [dn for dn in dns if dn not in already_crawl_dn] #将新发现未爬取的域名交给蜘蛛 for dn in dns: yield scrapy.Request("https://www." + dn, callback=self.parse) def close(spider, reason): print(already_crawl_dn)
现在已经可以抓取域名了,目前有个问题是这些域名存在列表(内存)中,随着程序运行内存会慢慢被占满。我没找的最新的全球域名数统计,但找到了:
截至2015年6月,中国域名总数为2231万个,其中“.CN”域名总数为1225万个,占中国域名总数比例为54.9%,“.中国”域名总数为26万个
假设目前全球域名总数1亿个,每个域名长度10个字符(统计了100个域名的平均长度)
查看1亿个域名所占用内存
In [147]: domainNames = ['xxxxxx.com'] * 100000000 In [148]: import sys In [149]: sys.getsizeof(domainNames) / 1024 / 1024 Out[149]: 762.9395141601562
占用了762M,以现在电脑配置绰绰有余了,在看看所需时间
抓取每个域名的平均实际1s(统计了100个域名的平均时间),1亿个需要4年。即使全球目前真的有1亿个域名,这个程序也不能将他们全部找到,因为为了节约时间我没有访问所有网页,
每个域名网站只访问了一次(只访问了主页)。