Python3.6.1 requests2.18.4 scrapy,beautifulsoup 开发工具sublime text 3
(此微博为博主原创,如果有想转载的同学请注明原博客链接,谢谢合作)
很多人会想,写爬虫为什么最好要用代理服务器来访问?这是因为很多网站都设置了反爬虫机制,因为大量的爬虫如果同时访问此网站,会给此网站的服务器带来很大的负担。如果同一IP在一定时间访问过于频繁的话,就有可能会被判定为爬虫,所以设置代理来访问网站。
想看网站具体有哪些限制,可以访问:网站+robots.txt,来查看此网站的robots协议。
首先声明,此微博只为演示。
1、先用scrapy框架,从网站上爬取IP作为使用的IP池,并存入ip_list.txt文档中
下面只给出spider代码:
'''
please in here defined yours spider
define crawler rules
'''
import scrapy
from agentIP.items import AgentipItem
class My_ip(scrapy.Spider):
name="ipsc"
allowed_domains=["xicidaili.com"]#域名
start_urls =["http://www.xicidaili.com/"]
def parse(self,response):
#response是一个html响应对象可以用xpath规则进行解析
ipall=response.xpath('//table[@id="ip_list"]/tr')
item=AgentipItem()
for each_ip in ipall:
S_ip=each_ip.xpath('.//td')
list=[]
if len(S_ip)==0:
continue
for j in S_ip:
c=j.xpath('./text()').extract()
if len(c)==0:
continue
list.append(c[0])
item['ips']=list[0]
item['port']=list[1]
yield item
2、再将爬取下来的IP写入数据库
代码:
import pymysql
def insert():
db=pymysql.connect(host='127.0.0.1',port=3306,user='root',password='******',db='******',use_unicode=True,charset='utf8')
cursor=db.cursor()
print('database connect scuccess')
sql='insert into iplist_1(ip,port) values(%s,%s)'
#sql='insert into gamerank (rank,g_name,g_type,g_status,g_hot) values(1,'hssd','sds','waasdd',2)'
#sql='insert into gamerank (rank,g_name,g_type,g_status,g_hot) values(%d,%s,%s,%s,%d)',([1,'hssd','sds','waasdd',2])
for list in lists:
try:
cursor.execute(sql,list)
print('insert success')
db.commit()
except Exception as e:
print('异常抛出:',e)
db.rollback()
db.close()
#从ip_list.txt读取IP和端口号
def read_file(file):
f=open(file,encoding='utf8')
lines=f.readlines()
list=[]
for i in lines:
i=i.strip()
a=i.split(',')
list.append(a)
f.close()
return list
#创建一个表格用来存储IP和端口号
def create():
db=pymysql.connect(host='127.0.0.1',port=3306,user='root',password='******',db='*****',use_unicode=True,charset='utf8')
cursor=db.cursor()
print('The database named yintao is connected scuccessful')
sql='create table IPlist_1 (ip varchar(40),port integer)'
try:
cursor.execute(sql)
print('create success')
except Exception as e:
print(e)
db.rollback()
finally:
db.close()
# create()
lists=read_file('F:\\Python\\scrapy\\agentIP\\ip_list.txt')
insert()
结果如下:
pip install fake-useragent
使用方法为
import fake_useragent
us=fake_useragent.UserAgent
us.random就可以随机出现一个useragent
4、实现
import re
import requests
from bs4 import BeautifulSoup
import pymysql
import random
import time
import fake_useragent
class Csdn():
def __init__(self,url,links=[],domains=[],headers={}):
self.url=url
self.links=links
self.domains=domains
self.headers=headers
def get_csdn(self):
ua=fake_useragent.UserAgent()
self.headers={
'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
"Accept-Encoding":'gzip, deflate',
'Accept-Language':'zh-CN,zh;q=0.8',
'Cache-Control':'max-age=0',
'Connection':'keep-alive',
'User-Agent':ua.random
}
#get the blogs links
html=requests.get(self.url)
html=html.text
obsoup=BeautifulSoup(html,'html5lib')
all_links=obsoup.find("div",id="article_list").find_all("span",class_='link_title')
for i in all_links:
for href in i.find_all('a'):
self.links.append('http://blog.csdn.net'+href.attrs['href'])
print('链接:',self.links)
def get_domain(self):
#连接数据库获得ip和端口号,用于设置代理
db=pymysql.connect(host='127.0.0.1',port=3306,user='root',password='******',db='*****',use_unicode=True,charset='utf8')
cursor=db.cursor()
print('database connect success')
sql='select ip,port from iplist_1'
try:
cursor.execute(sql)
print('execute success')
result=cursor.fetchall()
for row in result:
ip=row[0]
port=row[1]
domain="http://"+str(row[0])+":"+str(row[1])
self.domains.append(domain)
print('代理服务器:',self.domains)
db.commit()
except Exception as e:
print('Error occurred:',e)
db.rollback()
db.close()
def account_hit(self):
# 开始刷访问量
for _ in range(10):
ur=self.links[random.randint(0,len(self.links)-1)]
max=10
for i in range(0,max):
try:
s=random.randint(0,len(self.domains)-1)
#设置代理
proxies={ "http": self.domains[s], "https": self.domains[s],}
r=requests.get(ur,headers=self.headers,proxies=proxies,timeout=3)
print('响应结果:',r)
time.sleep(1)
except Exception as e:
print(e)
print('complete')
5、运行结果:
上面可以看出:响应结果为Response 200的是访问成功的。
不成功的原因是有些代理服务器,无法正常使用。
当然还有更牛逼的访问实现,那就是使用线程来实现了,比如将函数写入多个线程,那么运行速度是不是会更快呢?
代码只有自己去想了
还有的就是不得不说一下beautifulsoup的好处了,本来一开始准备用re模块就是正则表达式来找网页links,但是我发现正则出来的links,有很多的不是我们想要的,但是这个又不能排除,除非用精确匹配,那样写的代码就是大杂烩,有点失去了简洁的味道,所以我选择了beautifulsoup来找links,快速而且方便。
所以建议感兴趣的同学可以去好好理解一下beautifulsoup,这样会提高程序的编写速率。
送给大家两句话:keep learning ; Never give up easily。
希望此博客对你有所帮助。