需求分析
從一個門戶網站出發,試圖爬取該門戶網站所有鏈接,如此遞歸下去,發現新域名則保存起來,每個域名網站只爬取一次。有了這些數據在通過外部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億個域名,這個程序也不能將他們全部找到,因為為了節約時間我沒有訪問所有網頁,
每個域名網站只訪問了一次(只訪問了主頁)。