导入模块
from bs4 import BeautifulSoup
import urllib3
import urllib
import threading
爬虫是学python中最好玩的学习方法,也是方便生活、工作中的有效利器,爬虫帮我们工作,那会节省大量的人力。
在该博客中,分成5个步骤来简单教大家如何用好爬虫。最后贴出源码。
urllib3一般是爬虫中必用的打开网页的利器,西刺网站不需要验证用户,获取网页十分简单。若想进一步了解详见官网(英文):http://urllib3.readthedocs.io/en/latest/ ,中文优秀博客:https://blog.csdn.net/LookForDream_/article/details/78624594
#获取网页HTML码
def getContent(url):
http=urllib3.PoolManager()
response=http.request('get',url)
#网页返回200表示可打开网页
print('网页 %s 返回代码:%s'%(url,response.status))
return response.data
该步骤是爬虫中最核心的部分,要分析出爬取的网页的规律。网页规律分析不好,写出来的代码可能又臭又长。BeautifulSoup是较为容易上手的解析网页的爬虫工具,BeautifulSoup可调用xml、html.parser、lxml解析器,性能优点各有不同,而官网推荐我们使用lxml解析器。BeautifulSoup中文官网:https://blog.csdn.net/kikaylee/article/details/56841789
Proxys=[]
pages=5
#爬去西刺10页的代理IP
for i in range(0,pages):
url='http://www.xicidaili.com/nn/%d'%(i+1)
content=getContent(url) #获取网页内容
if content!=None:
soup=BeautifulSoup(content,'lxml')
#分析网页源码得,tr标签中class=''或class='odd'都满足
Tags=soup.find_all('tr',attrs={'class':'odd'})+soup.find_all('tr',attrs={'class':''})[1:]
#获取该页所有的代理IP
for tag in Tags:
t=tag.find_all('td')
ip=t[1].get_text()
post=t[2].get_text()
protocol=t[5].get_text().lower() #变小写
Proxys.append(protocol+'://'+ip+':'+post)
print('共爬取了%d个代理IP'%len(Proxys))
代码结果:
网页 http://www.xicidaili.com/nn/1 返回代码:200
网页 http://www.xicidaili.com/nn/2 返回代码:200
网页 http://www.xicidaili.com/nn/3 返回代码:200
网页 http://www.xicidaili.com/nn/4 返回代码:200
网页 http://www.xicidaili.com/nn/5 返回代码:200
共爬取了500个代理IP
在这里用的是urllib设置代理IP来测试代理IP是否有效。
def testProxy(pro):
protocol=pro.split(':')[0]
#设置urllib中的代理IP
opener=urllib.request.build_opener( urllib.request.ProxyHandler({protocol:pro}) )
urllib.request.install_opener(opener)
#若能打开test_url则保存该代理IP
try:
response=urllib.request.urlopen(test_url,timeout=timeout)
response.read()
except:
print("代理IP:%s 无效"%pro)
else:
if pro not in alive_Proxys:
alive_Proxys.append(pro)
单线程测试代理IP是十分缓慢的,故使用多线程。但在使用多线程中要注意join方法阻塞线程到结束。
test_url='http://baidu.com'
n=10 #线程数
timeout=3
alive_Proxys=[] #保存可用代理
pro=Proxys.pop()
while Proxys:
T=[]
for i in range(n):
t=threading.Thread(target=testProxy,args=(pro,))
T.append(t)
t.start()
if Proxys:
pro=Proxys.pop()
else:
break
#阻塞n个进程结束后再重新创建线程
for t in T:
t.join()
print("可用代理IP:%d"%len(alive_Proxys))
代码结果:
代理IP:http://114.228.74.205:6666 无效
代理IP:http://222.77.48.46:47437 无效
代理IP:http://223.241.118.205:18118 无效
代理IP:http://123.163.178.116:25746 无效
#中间省略了很多....
可用代理IP:339
with open('Proxys.txt','w') as fp:
for line in alive_Proxys:
fp.write("%s\n"%line)
print("写入完毕")
代码结果:
写入完毕
from bs4 import BeautifulSoup
import urllib3
import urllib
import threading
#获取网页HTML码
def getContent(url):
http=urllib3.PoolManager()
response=http.request('get',url)
print('网页 %s 返回代码:%s'%(url,response.status))
return response.data
#测试代理是否可用
def testProxy(pro):
protocol=pro.split(':')[0]
#设置urllib中的代理IP
opener=urllib.request.build_opener( urllib.request.ProxyHandler({protocol:pro}) )
urllib.request.install_opener(opener)
#若能打开test_url则保存该代理IP
try:
response=urllib.request.urlopen(test_url,timeout=timeout)
response.read()
except:
print("代理IP:%s 无效"%pro)
else:
if pro not in alive_Proxys:
alive_Proxys.append(pro)
#获取代理IP
Proxys=[]
pages=5
#爬去西刺10页的代理IP
for i in range(0,pages):
url='http://www.xicidaili.com/nn/%d'%(i+1)
content=getContent(url) #获取网页内容
if content!=None:
soup=BeautifulSoup(content,'lxml')
#分析网页源码得,tr标签中class=''或class='odd'都满足
Tags=soup.find_all('tr',attrs={'class':'odd'})+soup.find_all('tr',attrs={'class':''})[1:]
#获取该页所有的代理IP
for tag in Tags:
t=tag.find_all('td')
ip=t[1].get_text()
post=t[2].get_text()
protocol=t[5].get_text().lower()
Proxys.append(protocol+'://'+ip+':'+post)
print('共爬取了%d个代理IP'%len(Proxys))
#测试代理IP是否可用
test_url='http://baidu.com'
n=10 #线程数
timeout=3
alive_Proxys=[] #保存可用代理
pro=Proxys.pop()
while Proxys:
T=[]
for i in range(n):
t=threading.Thread(target=testProxy,args=(pro,))
T.append(t)
t.start()
if Proxys:
pro=Proxys.pop()
else:
break
#阻塞n个进程结束后再重新创建线程
for t in T:
t.join()
print("可用代理IP:%d"%len(alive_Proxys))
#写入文件
with open('Proxys.txt','w') as fp:
for line in alive_Proxys:
fp.write("%s\n"%line)
print("写入完毕")
谢谢大家的浏览,
希望我的努力能帮助到您,
共勉!