使用到的标准库有
requests #请求网页信息
time #调用其中的sleep()函数,对程序进行暂定,防止在短时间内抓取过于频繁导致被服务器拦截
random #用于生成随机数, 这里用来随机生成10-30的整数,用做程序等待的时间。
bs4 #处理html页面,需要安装BeautifulSoup安装库
pip install BeautifulSoup
pip install BeautifulSoup4普通抓取
支持环境:亲测支持python2.7/3.6
# -*- coding: utf-8 -*-
import time
import requests
import random
import os
from bs4 import BeautifulSoup
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
#设置要抓取的页面范围,以下为抓取1-4页。
page_number = list(range(1,5))
#抓取的链接
url = 'http://www.xicidaili.com/nn/'
#临时存储页面信息的文件
filename = 'html.txt'
# 通过for循环依次拼接链接
for i in page_number:
full_url = url + str(i)
# 设置请求的头部信息,伪装成浏览器。
headers = {'user-agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 UBrowser/6.2.4091.2 Safari/537.36'}
# 随机等待几秒,防止抓取过于频繁被锁定。
time.sleep(random.randint(5, 10))
print("正在抓取第" + str(i) + "页......")
# 通过前面拼接的链接,抓取页面信息
r = requests.get(full_url, headers=headers)
print("第" + str(i) + "页抓取完成!")
# 将抓取到的页面存入临时的文件
with open(filename, 'a') as f_obj:
f_obj.write(r.text)
print("开始过滤抓取的页面,请稍后......")
# 处理前面抓取到的文件
with open(filename) as f:
# 通过BeaufifulSoup来处理前面抓取的html内容
bsobj = BeautifulSoup(f.read(), 'html.parser')
# 过滤出html页面中标题位置元素信息,
title_list = bsobj.findAll('th')
# 过滤出html页面中IP、端口等信息。
ip_list = bsobj.findAll('td')
info_list = []
# 对ip、端口等信息进行处理,将处理的信息也写入info中,一行一条。
for ip_info in ip_list:
# with open('info.txt', 'a') as f:
text = ip_info.get_text().strip() + ' '
if text == ' ':
text = '填充 '
info_list.append(text.strip())
else:
info_list.append(text.strip())
print("信息过滤完成!\n开始测试代理的可用性~~~\n")
#删除列表中的空元素
while '' in info_list:
info_list.remove('')
#定义4个空列表,用来存放下面过滤出来的信息
ip = []
prot = []
location = []
type = []
#通过while循环过滤出IP、端口、地区和类型信息
a = 0
while a <= 10:
for i in info_list[a::10]:
if a == 1:
ip.append(i)
elif a == 2:
prot.append(i)
elif a == 3:
location.append(i)
elif a == 5:
type.append(i)
else:
break
a += 1
#依次从IP、端口、地区和类型列表中取出一个值,拼接成IP:Prot
#测试代理IP是否可用,如果可用,则写入it_works.txt文件中
while type:
i = ip.pop(0)
t = type.pop(0)
p = prot.pop(0)
l = location.pop(0)
url = i + ':' + str(p)
#防止过滤的信息中有空值,只有所有值均不为空的时候才进行测试
if i !='' and t !='' and p !='' and l !='':
try:
# r = requests.get('http://ip.chinaz.com/getip.aspx', proxies={'http': url}, timeout=2)
r = requests.get('http://2018.ip138.com/ic.asp', proxies={'http': url}, timeout=2)
except:
pass
else:
#只有响应代码在200-300之间才说明该代理IP可用,才会写入指定的文件中
if r.status_code >= 200 and r.status_code < 300:
print(url + ' ' + l + ' 这个代理可用!')
with open("it_works.txt", 'a') as f:
f.write(t + '\t')
f.write(i + '\t')
f.write(p + '\t')
f.write(l + '\n')
else:
pass # 如果不可用或超时直接跳过
else:
continue # 如果有值为空则直接处理下一组
#删除之前存储临时页面信息的文件
if os.path.exists(filename):
os.remove(filename)
print("信息过滤完成!请查看it_works.txt文件")使用scrapy抓取
先新建一个scrapy项目,
scrapy startproject djiango_test然后修改项目目录中items.py文件,增加如下内容
class DailiIpsItem(scrapy.Item):
ip = scrapy.Field()
port = scrapy.Field()
position = scrapy.Field()
type = scrapy.Field()
speed = scrapy.Field()
last_check_time = scrapy.Field()进到spiders目录,创建一个get_xici.py
# -*- coding: utf-8 -*-
import scrapy
from django_test.items import DailiIpsItem #因为我建的项目叫djiango_test,所以导入时全称为djiango_test.items
import pandas as pd #csv库
class XiciSpider(scrapy.Spider):
name = "xici"
allowed_domains = ["xicidaili.com"]
start_urls = (
'http://www.xicidaili.com/',
)
def start_requests(self):
res = []
for i in range(1, 2):
url = 'http://www.xicidaili.com/nn/%d'%i
req = scrapy.Request(url)
# 存储所有对应地址的请求
res.append(req)
return res
def parse(self, response):
table = response.xpath('//table[@id="ip_list"]')[0]
trs = table.xpath('//tr')[1:] #去掉标题行
items = []
name = ['ip', 'port', 'position', 'type', 'speed', 'last_check_time']
for tr in trs:
pre_item = DailiIpsItem()
pre_item['ip'] = tr.xpath('td[2]/text()').extract()[0]
pre_item['port'] = tr.xpath('td[3]/text()').extract()[0]
pre_item['position'] = tr.xpath('string(td[4])').extract()[0].strip()
pre_item['type'] = tr.xpath('td[6]/text()').extract()[0]
pre_item['speed'] = tr.xpath('td[7]/div/@title').re('\d+\.\d*')[0]
pre_item['last_check_time'] = tr.xpath('td[10]/text()').extract()[0]
items.append(pre_item)
html_csv = pd.DataFrame(columns=name, data=items)
html_csv.to_csv('xici.csv', mode='a')最后,执行命令,启动爬虫
scrapy crawl xici最后更新于