紧急赶制的Python抓取爬虫

前天一个朋友有紧急的要求:抓取一个工具书网站的上所有工具书信息,包括书名、作者、出版社、售价等等。还好原来做个一个python的爬虫程序,拿到这里修改修改还能运行,不过出现了几个问题:

1. 服务器拒绝。如果大量爬虫进程同时开始向服务器发出http请求,稍微有些安全意识的网站都会把你放到黑名单中,拒绝访问。比较好的方法就是使用互联网上免费的http proxy。

import urllib2

proxy = "61.219.107.164:8080"
url = "www.liyanyan.net"
proxy_support = urllib2.ProxyHandler({'http':proxy})
opener = urllib2.build_opener(proxy_support, urllib2.HTTPHandler)
urllib2.install_opener(opener)

print 'from proxy :'+proxy
html = urllib2.urlopen(url).read()

这样就能通过代理获取网页了。

2. 异常处理。原来的爬虫一旦遇到异常就会退出,添加异常后更具有健壮性,但是需要对python异常进行分类了解,针对不同的异常进行处理。

3. html内容分析。使用正则表达式太麻烦,不如使用SGMLParser这样现有的类更加方便。

4.多线程支持。在使用数十个proxy的情况下,如果不使用多线程的话就太浪费了,下面有个简单的使用thread和Queue配合的多线程ping

from threading import Thread
import subprocess
from Queue import Queue

num_threads = 4
queue = Queue()

ips = ["61.219.107.164", "92.50.163.114", "128.195.54.163", "129.107.35.132"]

def pinger(i,q):
	"""pings test"""
	while True:
		ip = q.get()
		print "Thread %s: Pinging %s" % (i,ip)
		ret = subprocess.call("ping -c 1 %s" % ip,
							shell=True,
							stdout=open('/dev/null','w'),
							stderr=subprocess.STDOUT)
		if ret == 0:
			print '%s is alive' % ip
		else:
			print '%s is not alive' % ip
		q.task_done()

for i in range(num_threads):
	worker = Thread(target=pinger , args= (i,queue))
	worker.setDaemon(True)
	worker.start()
for ip in ips:
	queue.put(ip)

queue.join()

Leave a Reply

Your email address will not be published. Required fields are marked *