抓取代理IP

写脚本从指定网站抓取数据的时候,免不了会被网站屏蔽IP。所以呢,就需要有一些IP代理。随便在网上找了一个提供免费IP的网站西刺做IP抓取。本次实践抓取的是其提供的国内匿名代理。可以打开网站查看一下源码,我们需要的内容在一个table区域内,通过BS4能很容易提取需要的信息。

Step 1:HTML页面获取

观察可以发现有我们需要的信息的页面url有下面的规律:www.xicidaili.com/nn/+页码。可是你如果直接通过get方法访问的话你会发现会出现500错误。原因其实出在这个规律下的url虽然都是get方法获得数据,但都有cookie认证。那么问题来了——怎么获得需要的cookie呢?

我们可以想一下,我们第一次通过浏览器访问该网站的主页是能打开的,其网站的各个子模块都可以打开。一定在某个时间段内我们的浏览器获得了该网站设置的cookie。清楚浏览器cookie,重新打开该网站首页,通过开发者工具可以发现我们打开首页的时候没有上传cookie,而是网站会下发cookie。接着打开我们上面找到的规律url页面,比对一下,发现我们上传的cookie就是在首页下发的cookie。这样就有办法了——编写脚本的时候,先访问一下首页获得cookie,再将获得的cookie添加到后续的请求中。

具体的代码如下:

import time
import json
import requests
from bs4 import BeautifulSoup

_headers={
			"Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
			"Accept-Encoding":"gzip, deflate, sdch",
			"Accept-Language":"zh-CN,zh;q=0.8",
			"Cache-Control":"max-age=0",
			"Host":"www.xicidaili.com",
			"Referer":"http://www.xicidaili.com/nn/",
			"Upgrade-Insecure-Requests":"1",
			"User-Agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.80 Safari/537.36"
			}

_cookies = None



def spider(total_page):
    url = "http://www.xicidaili.com/nn/"
    for i in range(1,total_page):
	if i % 100 == 0:
               #100个页面更新一次Cookie
		_cookies = requests.get("http://www.xicidaili.com/",headers=_headers).cookies
	r = requests.get(url+str(i),headers = _headers,cookies = _cookies)
	html_doc = r.text
	#print html_doc
	status_code = r.status_code
	print i,status_code
	r.close()
        
	with open("%s.html"%i,"w") as f:  #保存html,也可以直接信息提取
		f.write(html_doc.encode("utf-8"))
	time.sleep(1)
        _headers["Referer"]=url+str(i-1)

if __name__ == "__main__":
    _cookies = requests.get("http://www.xicidaili.com/",headers=_headers).cookies
    spider(200)

Step2 : 信息提取

分析html结构,使用BS4进行信息提取。具体代码如下:

from bs4 import BeautifulSoup
#import re
def parese(html_doc):
    ip_info = []
    soup = BeautifulSoup(html_doc,"lxml")
    for tag in soup.find_all(name = "table"):#,class_="odd"):#),attrs={"data-foo": "value"}):
	for tr in tag.find_all("tr",class_=True)#class_=True <=> re.compile("odd|")
		try:
			 tmp = tr.find_all("td",class_=None):
			 ip = tmp[0].string
			 port = tmp[1].string
		except:
			pass
		ip_info.append(zip(ip,port))
    return ip_info
posted @ 2016-05-03 20:01  Tacey Wong  阅读(2710)  评论(0编辑  收藏  举报