写在前面:
刚开始写博客,发现访问量有点不尽人意,想用着爬虫来提高一下啊csdn的访问量,无奈,一段时间内相同的ip不会累加访问量,所以只能通过代理ip来实现这个功能,先不说目的有没有达到,只是ip的获取还是遇到了些坑,写下这些内容,为后来者提供借鉴也为自己提供总结的机会。
项目主要实现内容:
运用多线程,获取网上的免费IP,以及对其进行验证。
项目主要涉及的库:
1.requests(这里也可以用urllib,不过我还是喜欢用requests库...)
2.BeautifulSoup(查找网页内容很好用)
3.threading(多线程)
项目代码编写:
思路:
ip代理思路还是很简单的,运用爬虫获取一些提供ip的网站提供的免费ip,在通过ip验证网站进行验证,并整理返回。
------------------------------------------不乱所以不华丽的分割线------------------------------------------
代码编写:
这里用的网站是:http://www.xicidaili.com/nn/1 # 1为第一页,2为第二页....
headers加一个:
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36"
就可以请求成功,然后运用:
soup = BeautifulSoup(re.text, "html5lib")
list_tr = soup.find_all("tr")
编码后获取其中的ip信息,并通过 请求 http://ip.chinaz.com/getip.aspx 可以的到ip可不可用 这里可以直接打开进行验证一下。
我们将获得的ip打包成:
ip = {"http": "http://" + tr.contents[3].text + ":" + tr.contents[5].text} #contents获取tr内的子元素
re = requests.get(url, proxies=ip, timeout=3)
运用proxies来使用代理,这里可以不用headers就可以请求了。如果超过timeout 设置的3秒就会抛出异常,所以需要一个异常处理。
----------
基本的ip代理我们已经完成了,但是我们这里会碰到的一个问题就是速度太慢了,我们验证一个ip需要3秒钟,100个就是5分钟,200个...显然我们希望能尽快的完成这项任务。
于是我们需要加入多线程:
thread = threading.Thread(target=函数名, args=(参数))
thread.start()
我们用for开出5个线程,每个线程请求网站中一页的ip地址,那我们的效率可以提高五倍,当然你也可以开的多一点,这个与你计算机的性能有关。
但是又有一些不尽人意的事情发生了,我们发现程序不会等待多线程执行完以后再继续执行以后的代码,也就是说我还没有获得能用的ip就已经开始模拟访问csdn了,这显然不可以。
所以我们希望让程序可以等待获取ip的多线程运行完之后再运行以后的代码,这里我们加入了join()。它可以开启线程守护(挺霸气的...守护,不禁让我想到了单身狗),让主线程等待开启守护的线程,当然也可以加入time参数表示多少秒,这里没必要可以自行百度。
所以我们的代码变成了这个样子:
for i in :#当然是伪代码 thread = threading.Thread(target=函数名, args=(参数)) threads.append(thread) # 线程守护等待子线程运行完再运行下面代码: for i in range(0, len(threads)): # t.setDaemon(True)#主线程一旦执行结束,则全部线程全部被终止执行, th[i + t].start() for t in range(0,len(threads)): th[i + t].join()
到这里我们的获取免费的ip代理已经完成了。
再多说几句:
当然我们还需要其他网站的免费ip,因为这个网站我TMD怕了10页将近两三百个ip只有那么四五个能用......
不过我们个人使用还是可以的,后期更新再说吧....源代码也贴一下了....
import requests from bs4 import BeautifulSoup import threading head = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36" } ipProxies = [] def GetIp(spage, epage): ips = [] url = "http://www.xicidaili.com/nn/" for i in range(spage, epage + 1): re = requests.get(url + str(i), headers=head) soup = BeautifulSoup(re.text, "html5lib") list_tr = soup.find_all("tr") for tr in list_tr: ip = {"http": "http://" + tr.contents[3].text + ":" + tr.contents[5].text} ips.append(ip) return ips def VerIP(ips): url = "http://ip.chinaz.com/getip.aspx" for ip in ips: try: re = requests.get(url, proxies=ip, timeout=3) if len(re.text) < 100 and re.text.find("html") < 0: print(re.text) ipProxies.append(ip) else: ips.remove(ip) print(ip) except: ips.remove(ip) print("Error:" + str(ip)) # 写入txt f = open("ipProxies.txt", 'a') for i in ipProxies: f.write(str(i) + "\n") f.close() def IpProxies(spage=1, epage=5): th = [] for i in range(spage, epage): ips = GetIp(i, i) thread = threading.Thread(target=VerIP, args=(ips,)) th.append(thread) # 线程守护等待子线程运行完再运行下面代码: for i in range(0, len(th), 5): for t in range(0, 5): if i+t < len(th): # t.setDaemon(True)#主线程一旦执行结束,则全部线程全部被终止执行, th[i + t].start() for t in range(0, 5): if i+t < len(th): th[i + t].join() return ipProxies if __name__ == "__main__":