1、 标准开局
所需依赖工具和库有:
scrapy | mysql8.0 |
---|---|
fake_useragent库 | random库 |
time库 | pymysql |
我们的目标为西刺代理
西刺代理
2、
安装好所需工具我们打开终端输入
#scrapy startproject 项目名(格式)
scrapy startproject xicidaili
然后它会自动生成一个目录,我们进入到他生成的spider目录这是我们写爬虫的主要目录,然后在当前目录输入一条命令生成一只爬虫:
#scrapy genspider 爬虫名称 要爬网站的域名
scrapy genspider xici xicidaili.com
然后用pycharm工具打开刚刚创建好的项目
3、在根目录创建一个start.py文件(上图已显示)
在此文件里写入
from scrapy import cmdline
#此文件是方便我们在pycharm运行项目
cmdline.execute("scrapy crawl xici".split())
4、打开setiings.py文件
找到下面代码把注释去掉,连接数据库需要
ITEM_PIPELINES = {
'xicidaili.pipelines.XicidailiPipeline': 300,
}
然后找到DOWNLOADER_MIDDLEWARES开头的,写入(这是我们等下要写的ip代理和头部代理中间件)
'xicidaili.middlewares.my_proxy': 243,
'xicidaili.middlewares.my_userAgent': 245,
然后在文件最下面写入我们的代理ip,(这些代理ip要自己找,我的有可能失效了,在此项目中最好要找https高匿名的ip,我们请求的网站是https类型的)
IPPOOL = [
{'ipaddr':'218.86.200.26:8118'},
{'ipaddr':'60.168.71.254:8118'},
{'ipaddr':'119.254.94.71:42788'},
{'ipaddr':'123.132.232.254:37638'},
{'ipaddr':'117.94.213.165:8118'},
{'ipaddr':'1121.227.6.244:8888'},
{'ipaddr':'115.53.202.236:8118'},
{'ipaddr':'113.12.202.50:40498'},
{'ipaddr':'119.147.137.79:8008'},
{'ipaddr':'58.254.220.116:52470'},
{'ipaddr':'218.249.45.162:35586'},
{'ipaddr':'115.238.59.86:53400'},
{'ipaddr':'115.231.5.230:44524'},
{'ipaddr':'61.164.39.66:53281'},
{'ipaddr':'117.88.177.100:3000'},
{'ipaddr':'113.116.179.245:8118'},
{'ipaddr':'115.219.109.115:8010'},
{'ipaddr':'121.237.148.56:3000'},
{'ipaddr':'121.234.31.44:8118'},
{'ipaddr':'58.58.213.55:8888'}
]
5、进入middlewares.py文件(scrapy是在这里写中间件)
我们这里先导入需要的库
#UserAgent代理库
from fake_useragent import UserAgent
import random
#刚刚我们写的代理ip
from xicidaili.settings import IPPOOL
在最后写入一下代码
#ip代理类
class my_proxy(object):
def process(self,request,spider):
#随机抽出ip
this_ip = random.choice(IPPOOL)
#为我们的请求添加代理ip
request.meta["proxy"] = "https://" + this_ip("ipaddr")
#UserAgent代理类
class my_userAgent(object):
def process_request(self,request,spider):
ua = UserAgent()
#为我们的请求添加随机的头部代理
request.headers['User-Agent'] = ua.random
6、打开items.py文件(定义好字段)
在文件里直接写入
#ip
ip = scrapy.Field()
#ip类型
types = scrapy.Field()
#ip所在地址
address = scrapy.Field()
#ip端口
port = scrapy.Field()
7、高潮来啦,打开spiders下的xici.py文件
到这里我们就要写我们爬虫的逻辑了,我们先分析一下我们的网站,我们数据在什么标签下,
通过分析,我们的数据是在一个tr标签中的但是,它们是在一个tr标签中class=‘’或者class=‘odd’中,是隔一个就重复的,所以我们的代码
并且知道它的下一页的链接也是有规律的
#先把这两定位,等下用循环爬它们包含的数据
itm = response.xpath("//tr[@class='odd']")
itm2 = response.xpath("//tr[@class='']")
以下是这个文件的全部代码:
import scrapy
import time
import random
from xicidaili.items import XicidailiItem
class XiciSpider(scrapy.Spider):
name = 'xici'
allowed_domains = ['xicidaili.com']
start_urls = ['https://www.xicidaili.com/nn/']
def parse(self, response):
items = XicidailiItem()
print(response.meta)
print(response.status)
print(response.headers)
itm = response.xpath("//tr[@class='odd']")
itm2 = response.xpath("//tr[@class='']")
# x和y是用来判断爬了多少条数据,但它达到一定数据时他会停下随机的秒数
x = 0
y = 0
for i in itm:
x = x + 1
ip = i.xpath("./td[2]//text()").get()
port = i.xpath("./td[3]//text()").get()
types = i.xpath("./td[6]//text()").get()
addr = i.xpath("./td[4]/a//text()").get()
#但x可以整除40就会停止随机秒数爬虫
if x % 40 == 0:
numbter = random.randint(5, 20)
time.sleep(numbter)
items['ip'] = str(ip)
items['port'] = str(port)
items['address'] = str(addr)
items['types'] = str(types)
yield items
for i in itm2:
y = y + 1
ip2 = i.xpath("./td[2]//text()").get()
port2 = i.xpath("./td[3]//text()").get()
types2 = i.xpath("./td[6]//text()").get()
addr2 = i.xpath("./td[4]/a//text()").get()
#但月可以整除40就会停止随机秒数爬虫
if y % 40 == 0:
numbter = random.randint(5, 15)
time.sleep(numbter)
items['ip'] = str(ip2)
items['port'] = str(port2)
items['address'] = str(addr2)
items['types'] = str(types2)
yield items
#获取下一页网址(这里不是完整的)
next_link = response.xpath("//a[@class='next_page']/@href").get()
if next_link:
#把完整的网站回调
yield scrapy.Request("https://www.xicidaili.com" + next_link, callback=self.parse)
print(next_link)
print(str(x) + '\t' + str(y))
gg = x + y
print(gg)
哦,忘了这是数据库(先创建一个名为python001的库在创建以下的表):
create table xicidaili(
Id int auto_increment,
IP varchar(30) not null,
Port varchar(15) not null,
Types varchar(10) not null,
Address varchar(50) not null,
Key (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;
嗯嗯嗯嗯嗯,可以运行了
但是博主爬到六十多页时程序结束了,但是我们网站有四千多页,
嗯嗯,对,博主的ip给封了,不知道什么时候才能解封,但也爬了一万多的ip
在mysql数据库里你可以输入:
select * from xicidaili;
#查看https类型的ip
select * from xicidaili WHERE Types = 'HTTPS';
select * from xicidaili WHERE Types = 'HTTP';
为什么突然结束呢?
我们有设置ip代理,头部代理,随机停止的秒数,感觉我们的爬虫挺像人的操作的,其实我们用的博主觉得我们ip代理不够,我们才用了20多个,
可以用增加代理ip数,或者用分布式爬虫
其实我们用的都是固定ip,我们可以购买现在市场的动态ip代理本机,博主用翻墙的软件,代理一下本机的ip又可以访问xicidaili.com,好了结束啦!
如果不知道怎么取出和验证ip池的可用性的请看:提取存在mysql数据库的ip,并验证ip的可用性