python爬虫:将域名列表按注册时间排序

工具不能提高生产力,那就不是生产力工具,那就可以果断弃之。

断断续续的学习python,根据网络上的教程做了些爬虫实验,无非也就是按别人的思路重新操作一遍,纵然成功,成就感也大打折扣,实用价值也并不高。

今天开始实现一个具体的、官方未给出解决方案的需求,把ename的竞拍列表按域名的注册时间排序。初步想到的是,先获取域名列表,把列表中的域名的whois信息逐个爬出来,根据注册时间再排序输出。

这里面应先实现的是,输入一个域名,将他的whois信息存入数组。这里面应该有很多问题,例如.com等国际域名和.cn等国别域名可能在字段上有差异,查询whois信息应使用哪家接口等。废话不多说,抿口咖啡先干起来。

(2017年1月14日14点16分)

import urllib.request

whois = urllib.request.urlopen(“http://whois.chinaz.com/linchun.org”)

mybytes = whois.read()

mystr = mybytes.decode(“utf8”)

whois.close()

print(mystr)

#用chinaz的接口实现whois的查询

#易名接口:http://whois.ename.net/linchun.org 403错误,后续模拟浏览器来

#西部数码:http://www.west.cn/web/whois/whoisinfo?domain=linchun.org uft8编码错误 回头来修

import requests

r = requests.get(url=’http://linchun.org’)  # 最基本的GET请求

print(r.status_code)  # 获取返回状态

r = requests.get(url=’http://linchun.org’, params={‘wd’: ‘python’})  # 带参数的GET请求

print(r.url)

print(r.text)  # 打印解码后的返回数据

#使用第三方库requests

import requests

r = requests.get(url=’http://whois.chinaz.com/linchun.org’)  # 最基本的GET请求

print(r.status_code)  # 获取返回状态

print(r.url)

print(r.text)  # 打印解码后的返回数据

#用requests实现查询whois功能,使用pip install requests安装

#西部数码和易名,还是要模拟浏览器才行

import requests

from bs4 import BeautifulSoup

r = requests.get(url=’http://whois.chinaz.com/linchun.org’)  # 最基本的GET请求

soup = BeautifulSoup(r.text, “lxml”) #这儿取requests对象的text属性,『lxml』可以换成html5lib,html.parser等

print(soup.prettify)

#用BeautifulSoup处理网页,输出标准化的网页代码

import requests

from bs4 import BeautifulSoup

import re

r = requests.get(url=‘http://whois.chinaz.com/linchun.org’)  # 最基本的GET请求

soup = BeautifulSoup(r.text, “lxml”) #这儿取requests对象的text属性

reg = re.compile(“\w+年\w+月\w+日”)

reg = soup.find_all(text=reg)

lens=len(reg)#获取列表的长度,应该只有2(注册时间,过期时间)或者3(更新时间,注册时间,更新时间)

i=1#标记执行次数

for times in reg:

    if(lens<=2): #当列表小于等于2时,直接打印

        print(times)

        break#打印了就跳出循环

    elif (i>=2):#当列表大于2时,且执行第二次时

        print(times)#打印

        break

    i+=1#执行计数器

#用最原始的办法,终于得到了域名的注册时间

以上部分算是简陋的得到了域名注册时间,现在需要将域名列表抓取出来了,这里面涉及的问题是对爬虫进行伪装,否则返回的是403。

import requests
from bs4 import BeautifulSoup
url = "http://auction.ename.com/tao/buynow"
headers = {
    'User-Agent':'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6'
}
r = requests.get(url,headers=headers)  # 模拟浏览器
soup = BeautifulSoup(r.text, "lxml") #这儿取requests对象的text属性,『lxml』可以换成html5lib,html.parser等
print(soup.prettify)

#以上,可以获得网页的html代码了,下面是想办法提取我们想要的部分。 这儿涉及的问题是,提取XXXXXX.XXX的域名数据,存入某个容器,以方便后面查找。这个网页他使用了ajax动态加载技术,需要再进一步研究。

#用谷歌浏览器,Option+command+I打开浏览器工具,找到Netword,找到XHR,观察到以下几个文件在变化 ,地址如下:

http://auction.ename.com/tao/buynow?ajax=1&domainsld=&domaintld%5B%5D=3&domainlenstart=1&domainlenend=&domaingroup=11&bidpricestart=0&bidpriceend=&finishtime=0&registrar=0&sort=2&hidenobider=0&inhidenobider=0&bidstartone=0&sldtypestart=0&sldtypeend=0&transtype=1&type=0&per_page=60&page=4&is_index=1&flag=&skipword1=&skipstart1=0&skipend1=0&skipword2=undefined&skipstart2=0&skipend2=0&domain=2&exptime=0&selectTwo=6,6

http://auction.ename.com/tao/buynow?ajax=1&domainsld=&domaintld%5B%5D=3&domainlenstart=1&domainlenend=&domaingroup=11&bidpricestart=0&bidpriceend=&finishtime=0&registrar=0&sort=2&hidenobider=0&inhidenobider=0&bidstartone=0&sldtypestart=0&sldtypeend=0&transtype=1&type=0&per_page=80&page=5&is_index=1&flag=&skipword1=&skipstart1=0&skipend1=0&skipword2=undefined&skipstart2=0&skipend2=0&domain=2&exptime=0&selectTwo=6,6

http://auction.ename.com/tao/buynow?ajax=1&domainsld=&domaintld%5B%5D=3&domainlenstart=1&domainlenend=&domaingroup=11&bidpricestart=0&bidpriceend=&finishtime=0&registrar=0&sort=2&hidenobider=0&inhidenobider=0&bidstartone=0&sldtypestart=0&sldtypeend=0&transtype=1&type=0&per_page=100&page=6&is_index=1&flag=&skipword1=&skipstart1=0&skipend1=0&skipword2=undefined&skipstart2=0&skipend2=0&domain=2&exptime=0&selectTwo=6,6

http://www.bejson.com/里面把json数据格式化一下,看到了浏览器中久违的样式。这就对了,真实数据找到了,离成功也更近了,下面可以去分析和封装了。

import requests

from bs4 import BeautifulSoup

import re

import json

url = “http://auction.ename.com/tao/buynow?ajax=1&domainsld=&domaintld[]=3&domainlenstart=1&domainlenend=&domaingroup=11&bidpricestart=0&bidpriceend=&finishtime=0&registrar=0&sort=2&hidenobider=0&inhidenobider=0&bidstartone=0&sldtypestart=0&sldtypeend=0&transtype=1&type=0&per_page=100&page=6&is_index=1&flag=&skipword1=&skipstart1=0&skipend1=0&skipword2=undefined&skipstart2=0&skipend2=0&domain=2&exptime=0&selectTwo=6,6”

headers = {

    ‘User-Agent’:’Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6′

}

r = requests.get(url,headers=headers)  # 模拟浏览器

soup = BeautifulSoup(r.text, “lxml”) #这儿取requests对象的text属性,『lxml』可以换成html5lib,html.parser等

soup=json.loads(soup.string)

print(soup)#最外层的数据

print(soup[‘data’][0])#第一个域名的字典

print(soup[‘data’][0][‘t_dn’])#第一个字典的列表,tdn就是域名

i=len(soup[‘data’])-1

while i>=0:

    print(soup[‘data’][i][‘t_dn’])  # 将最里面的域名,全部打印出来

    i-=1

#通过以上这段代码,将json数据里的域名打印出来。这里面的坑是json有多层嵌套,要理清他的结构然后提取出来。

import requests

from bs4 import BeautifulSoup

import re

import json

retime = re.compile(“\w+年\w+月\w+日”)

url = “http://auction.ename.com/tao/buynow?ajax=1&domainsld=&domaintld[]=3&domainlenstart=1&domainlenend=&domaingroup=11&bidpricestart=0&bidpriceend=&finishtime=0&registrar=0&sort=2&hidenobider=0&inhidenobider=0&bidstartone=0&sldtypestart=0&sldtypeend=0&transtype=1&type=0&per_page=100&page=6&is_index=1&flag=&skipword1=&skipstart1=0&skipend1=0&skipword2=undefined&skipstart2=0&skipend2=0&domain=2&exptime=0&selectTwo=6,6”

whoisurl=”http://whois.chinaz.com/”

headers = {

    ‘User-Agent’:’Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6′

}

r = requests.get(url,headers=headers)  # 模拟浏览器

soup1 = BeautifulSoup(r.text, “lxml”) #这儿取requests对象的text属性,『lxml』可以换成html5lib,html.parser等

soup2=json.loads(soup1.string)

i=len(soup2[‘data’])-1

while i>=0:

    web=soup2[‘data’][i][‘t_dn’]#获得的域名

    r1 = requests.get(whoisurl+web)  # 最基本的GET请求

    soup3 = BeautifulSoup(r1.text, “lxml”)  # 这儿把chinaz的数据装到soup1

    retime1 = soup3.find_all(text=retime)#这儿在找年月日入数组reg

    lens = len(retime1)  # 获取列表的长度,应该只有2(注册时间,过期时间)或者3(更新时间,注册时间,更新时间)

    c = 1  # 标记执行次数

    for times in retime1:

        if (lens <= 2):  # 当列表小于等于2时,直接打印

            print(web+’     注册日期>>>>>      ‘+times)#打印域名和注册时间

            break  # 打印了就跳出循环

        elif (c >= 2):  # 当列表大于2时,且执行第二次时

            print(web+’     注册日期>>>>>      ‘+times)  # 打印

            break

        c += 1  # 执行计数器

    i-=1

以上代码,实现易名一个列表的注册日期查询。下面将要提高代码的自动化、可读性、效率。

import requests

from bs4 import BeautifulSoup

import re

import json

import io

import time

retime = re.compile(“\w+年\w+月\w+日”)

url=”http://auction.ename.com/tao/buynow?ajax=1&domainsld=&domaintld[]=0&domainlenstart=1&domainlenend=&domaingroup=0&bidpricestart=0&bidpriceend=&finishtime=0&registrar=0&sort=1&hidenobider=0&inhidenobider=0&bidstartone=0&sldtypestart=0&sldtypeend=0&transtype=1&type=0&per_page=20&page=2&is_index=1&flag=&skipword1=&skipstart1=0&skipend1=0&skipword2=undefined&skipstart2=0&skipend2=0&domain=2&exptime=0&selectTwo=”

whoisurl=”http://whois.chinaz.com/”#whois的地址前缀

furl=”/Users/linchun/pytxt/domain.txt”#txt文件的路径

headers = {

    ‘User-Agent’:’Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6′

}#浏览器头部

r = requests.get(url,headers=headers)  # 模拟浏览器

soup1 = BeautifulSoup(r.text, “lxml”) #这儿取requests对象的text属性,『lxml』可以换成html5lib,html.parser等

soup2=json.loads(soup1.string)#将得到的json数据转换成字典

i=len(soup2[‘data’])-1#字典中,data列表的个数

while i>=0:#列表坐标从最后一个开始,执行到第一个

    time.sleep(1)#等待时间,秒,不要太快的去爬别人网站

    web=soup2[‘data’][i][‘t_dn’]#获得字典嵌套里的域名

    r1 = requests.get(whoisurl+web)  # 得到一个requests数据,是whois前缀加上要查询的域名

    soup3 = BeautifulSoup(r1.text, “lxml”)  # 这儿把chinaz查到的的数据装到soup3

    retime1 = soup3.find_all(text=retime)#这儿在找日期数据放入数组retime1

    lens = len(retime1)  # 获取列表的长度,应该只有2(注册时间,过期时间)或者3(更新时间,注册时间,更新时间)

    c = 1  # 标记执行次数

    for times in retime1:

        if (lens <= 2):  # 当列表小于等于2时,直接打印

            print(“{0:20}注册日期:  {1:20}”.format(web, times))#打印域名和注册时间

            with open(furl, “a”) as f:

                f.write(“{0:20}注册日期:  {1:20}\n”.format(web, times))

            break  # 打印了就跳出for循环

        elif (c >= 2):  # 当列表大于2时,且执行第二次时

            print(“{0:20}注册日期:  {1:20}”.format(web,times))#这儿用到一个format方法,比python2.X里面的%X这种好用太多,相当于定义了一个数组,后面的参数是字符的宽度。

            with open(furl, “a”) as f:

                f.write(“{0:20}注册日期:  {1:20}\n”.format(web, times))#print和write是一样的用法

            break

        c += 1  # for的计数器,只打印第一个或第二个

    i-=1#这个是while的计数器,从最后一个执行到第一个

#这儿实现的是把上面的数据输出到本地,另外就是输出的时候用了format格式化了一下。下面要处理的就是对易名的来路链接进行一个研究,让这个程序可以多跑一些,达到几千条级别,至于排序,反而是最不重要的。

import requests

from bs4 import BeautifulSoup

import re

import json

import io

import time

headers = {

        ‘User-Agent’:’Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6′

    }#浏览器头部

retime = re.compile(“\w+年\w+月\w+日”)

url1=”http://auction.ename.com/tao/buynow?ajax=1&domainsld=&domaintld%5B%5D=1&domainlenstart=1&domainlenend=&domaingroup=11&bidpricestart=0&bidpriceend=&finishtime=0&registrar=0&sort=2&hidenobider=0&inhidenobider=0&bidstartone=0&sldtypestart=0&sldtypeend=0&transtype=1&type=0&per_page=”

url2=”&page=”

url3=”&is_index=1&flag=&skipword1=&skipstart1=0&skipend1=0&skipword2=undefined&skipstart2=0&skipend2=0&domain=2&exptime=0&selectTwo=6,6″

whoisurl = “http://whois.chinaz.com/”  # whois的地址前缀

per_page=0

page=0

furl = “/Users/linchun/pytxt/dotcom.txt”  # txt文件的路径

while page<4066:

    per_page=per_page+20

    page=page+1

    url=url1+str(per_page)+url2+str(page)+url3

    r = requests.get(url,headers=headers)  # 模拟浏览器

    soup1 = BeautifulSoup(r.text, “lxml”) #这儿取requests对象的text属性,『lxml』可以换成html5lib,html.parser等

    soup2=json.loads(soup1.string)#将得到的json数据转换成字典

    i=len(soup2[‘data’])-1#字典中,data列表的个数

    while i>=0:#列表坐标从最后一个开始,执行到第一个

        web=soup2[‘data’][i][‘t_dn’]#获得字典嵌套里的域名

        price=soup2[‘data’][i][‘t_now_price’]#获得字典嵌套里的价格

        r1 = requests.get(whoisurl + web)  # 得到一个requests数据,是whois前缀加上要查询的域名

        soup3 = BeautifulSoup(r1.text, “lxml”)  # 这儿把chinaz查到的的数据装到soup3

        retime1 = soup3.find_all(text=retime)  # 这儿在找日期数据放入数组retime1

        lens = len(retime1)  # 获取列表的长度,应该只有2(注册时间,过期时间)或者3(更新时间,注册时间,更新时间)

        c = 1  # 标记执行次数

        for times in retime1:

            if (lens <= 2):  # 当列表小于等于2时,直接打印

                print(“{0:15}注册日期: {1:10}   价格:{2:2}”.format(web, times,price))  # 打印域名和注册时间和价格

                with open(furl, “a”) as f:

                    f.write(“{0:15}注册日期: {1:10} 价格:{2:2}\n”.format(web, times,price))

                break  # 打印了就跳出for循环

            elif (c >= 2):  # 当列表大于2时,且执行第二次时

                print(“{0:15}注册日期: {1:10}   价格:{2:2}”.format(web, times,price)) #这儿用到一个format方法,比python2.X里面的%X这种好用太多,相当于定义了一个数组,后面的参数是字符的宽度。

                with open(furl, “a”) as f:

                    f.write(“{0:15}注册日期: {1:10} 价格:{2:2}\n”.format(web, times,price))  # print和write是一样的用法

                break

            c += 1  # for的计数器,只打印第一个或第二个

        i -= 1  # 这个是while的计数器,从最后一个执行到第一个

#以上代码和上一段类似,为输出.com的域名、注册时间、价格等信息到文本文件,另外再把一些固定的变量放到了循环之外。下一步还要加入异常处理,多线程,竞拍列表等功能。