频道栏目
首页 > 程序开发 > Web开发 > Python > 正文
python爬虫抓取心得分享
2013-03-10 22:38:03           
收藏   我要投稿
/**

author: insun

title:python 爬虫抓取心得分享

blog:http://yxmhero1989.blog.163.com/blog/static/112157956201311821444664/

**/   

0x1.urllib.quote('要编码的字符串')

如果你要在url请求里面放入中文,对相应的中文进行编码的话,可以用:

urllib.quote('要编码的字符串')

 

    query =  urllib.quote(singername)

    url = 'http://music.baidu.com/search?key='+query

    response = urllib.urlopen(url)

    text = response.read()

 

 

0x2. get or post  urlencode

如果在GET需要一些参数的话,那我们需要对传入的参数进行编码。

 

import urllib

def url_get():

    import urllib

    params = urllib.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0})

    f = urllib.urlopen("http://www.musi-cal.com/cgi-bin/query?%s" % params)

    print f.read()

 

def url_post():

    import urllib

    params = urllib.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0})

    f = urllib.urlopen("http://www.musi-cal.com/cgi-bin/query", params)

    print f.read()

 

0x3.urllib urllib2 proxy 代理

如果你请求对方的网页,确不想被封IP的话,这个时候就要用到代理了,其实用urllib代理还是比较简单的:

import urllib

def url_proxy():

    proxies = {'http':'http://211.167.112.14:80'}#或者proxies = {'':'211.167.112.14:80'}

    opener = urllib.FancyURLopener(proxies)

    f = opener.open("http://www.dianping.com/shanghai")

    print f.read()

只用一个代理IP的话 有时候弄巧成拙了 恰好被大众点评给检测出来了

401

211.167.112.14

python-urllib/1.17

python urllib urllib2抓取心得分享 - InSun - Minghacker is Insun

 那么就试试多个IP代理

import urllib

def url_proxies():

    proxylist = (

            '211.167.112.14:80',

            '210.32.34.115:8080',

            '115.47.8.39:80',

            '211.151.181.41:80',

            '219.239.26.23:80',

            )

    for proxy in proxylist:

        proxies = {'': proxy}

        opener = urllib.FancyURLopener(proxies)

        f = opener.open("http://www.dianping.com/shanghai")

        print f.read()

这回没问题了。

 

有的时候要模拟浏览器 ,不然做过反爬虫的网站会知道你是robot

例如针对浏览器的限制我们可以设置User-Agent头部,针对防盗链限制,我们可以设置Referer头部

有的网站用了Cookie来限制,主要是涉及到登录和限流,这时候没有什么通用的方法,只能看能否做自动登录或者分析Cookie的问题了。

 

仅仅是模拟浏览器访问依然是不行的,如果爬取频率过高依然会令人怀疑,那么就需要用到上面的代理设置了

import urllib2

def url_user_agent(url):

    '''

    proxy = 'http://211.167.112.14:80'

    opener = urllib2.build_opener(urllib2.ProxyHandler({'http':proxy}), urllib2.HTTPHandler(debuglevel=1))

    urllib2.install_opener(opener)

    '''

    i_headers = {"User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.1) Gecko/20090624 Firefox/3.5",\

                 "Referer": 'http://www.dianping.com/'}

    req = urllib2.Request(url, headers=i_headers)

 

    return urllib2.urlopen(req).read()

 

#print url_user_agent('http://www.dianping.com/shanghai')

 就算设置了代理,代理的ip也有可能被封,还有另外一种终极的办法来防止被封,那便是使用time库的sleep()函数。

import time

for i in range(1,10):

    ....#抓取逻辑

    time.sleep(5)

 

 

 

抓的地址是http://www.dianping.com/shanghai

直接抓http://www.dianping.com的话会location到城市列表去 反而达不到效果

header: Location: /citylist

 

提供一段代理IP

proxylist = (

            '211.167.112.14:80',

            '210.32.34.115:8080',

            '115.47.8.39:80',

            '211.151.181.41:80',

            '219.239.26.23:80',

            '219.157.200.18:3128',

            '219.159.105.180:8080',

            '1.63.18.22:8080',

            '221.179.173.170:8080',

            '125.39.66.153:80',

            '125.39.66.151:80',

            '61.152.108.187:80',

            '222.217.99.153:9000',

            '125.39.66.146:80',

            '120.132.132.119:8080',

            '119.7.221.137:82',

            '117.41.182.188:8080',

            '202.116.160.89:80',

            '221.7.145.42:8080',

            '211.142.236.131:80',

            '119.7.221.136:80',

            '211.151.181.41:80',

            '125.39.66.131:80',

            '120.132.132.119:8080',

            '112.5.254.30:80',

            '106.3.98.82:80',

            '119.4.250.105:80',

            '123.235.12.118:8080',

            '124.240.187.79:80',

            '182.48.107.219:9000',

            '122.72.2.180:8080',

            '119.254.90.18:8080',

            '124.240.187.80:83',

            '110.153.9.250:80',

            '202.202.1.189:80',

            '58.67.147.205:8080',

            '111.161.30.228:80',

            '122.72.76.130:80',

            '122.72.2.180:80',

            '202.112.113.7:80',

            '218.108.85.59:81',

            '211.144.72.154:80',

            '119.254.88.53:8080',

            '121.14.145.132:82',

            '114.80.149.183:80',

            '111.161.30.239:80',

            '182.48.107.219:9000',

            '122.72.0.28:80',

            '125.39.68.131:80',

            '118.244.190.6:80',

            '120.132.132.119:88',

            '211.167.112.15:82',

            '221.2.80.126:8888',

            '219.137.229.214:3128',

            '125.39.66.131:80',

            '61.181.22.157:80',

            '115.25.216.6:80',

            '119.7.221.137:82',

            '221.195.42.195:8080',

            '119.254.88.53:8080',

            '219.150.254.158:8080',

            '113.9.163.101:8080',

            '222.89.154.14:9000',

            '114.141.162.53:8080',

            '218.5.74.199:3128',

            '61.152.108.187:80',

            '218.76.159.133:80',

            '59.34.57.88:8080',

            '118.244.190.34:80',

            '59.172.208.189:8080',

            '116.236.216.116:8080',

            '111.161.30.233:80',

            '220.248.237.234:8080',

            '121.14.145.132:82',

            '202.114.205.125:8080'

            )

 

 

Proxy的使用相当广泛,对于单个应用来说,爬虫是很容易被封禁,如果使用Proxy模式,就能降低被封的风险,所以有需求的同学需要仔细看下Python urllib2对于Proxy的使用:

 

0x4.抓取下拉加载或者点击加载的页面方法:

 

加载中的内容应该是ajax请求的,对付ajax请求没有什么好的办法,只有抓取页面的JS,分析JS进行抓取

 

解决方案:

1.傻傻的全部下拉完 全部点击加载完(对少量数据还行,大量数据的站去死吧) 在Firefox里面copy出源码信息 进

行正则匹配

    2.HttpFox抓包  直接抓ajax地址的数据  分析ajax链接 变换参数  取得json后再正则

 

0x5.正则处理

python对正则表达式的支持模块。如果http库有选择的余地外,re几乎是没有选择余地的工具。因为有正则表达式的存在,所以让我们可以很灵活的去抠取抓取过来的完整html中所需要的部分。

 

当然,这篇文章不会详细解释正则表达式,因为如果要系统的介绍正则表达式,或许可以写一本书了。这里只简单提一下我们后面会用到的python正则表达式的用法。

 

re.compile()。如果正则表达式比较多,请一 定要先用这个方法先行编译正则表达式,之后再正则表达式的使用就会很非常快,因为大家都知道,python文件在第一次运行会分别创建一个字节码文件,如 果正则表达式作为字符串的时候,在运行时才会被编译,是会影响到python的执行速度的。

 

 

 

compile()返回的是一个re对象,该对象拥有re库的search(), match(), findall()等方法,这三个方法,在后面会被频繁的用到,生成被编译的re对象还有一个好处是调用方法不用再传入字符串的正则表达式。

 

search()主要用来校验正则表达式能否匹配字符串中的一段,通常用来判断该页面是否有我需要的内容。

 

 

 

match()用来判断字符串是否完全被一个正则表达式匹配,后面用的比较少。

 

 

 

findall()用来搜索正则表达式在字符串中的所有匹配,并返回一个列表,如果没有任何匹配,则返回一个空列表。

 

 

 

带有子组的正则表达式,findall()返回的列表中的每个元素为一个元组,正则表达式中有几个子组,元组中就会有几个元素,第一个元素为第一个括号中的子组匹配到的元素,以此类推。

 

findall()和search()是有类似之处的,都是搜索正则表达式在字符串中的匹配,但是findall()返回一个列表,search()返回一个匹配对象,而且findall()返回的列表中有所有匹配,而search()只返回第一个匹配的匹配对象。

 

0x6.Reference:

 

python urllib下载网页

http://www.cnpythoner.com/post/pythonurllib.html

 

关于不得不在python中使用代理访问网络的方法

http://blogread.cn/it/wap/article/1967

 

python使用urllib2抓取防爬取链接

http://www.the5fire.net/python-urllib2-crawler.html

 

Python实战中阶(一)——爬取网页的一点分享

http://blog.goodje.com/2012-08/python-middle-action-web-crawler.html

 

Python Urllib2使用:代理及其它

http://isilic.iteye.com/blog/1806403

 

Python urllib2递归抓取某个网站下图片 

http://blog.csdn.net/wklken/article/details/7364899

 

用Python抓网页的注意事项

http://blog.raphaelzhang.com/2012/03/issues-in-python-crawler/

 

urllib.urlretrieve下载图片速度很慢 + 【已解决】给urllib.urlretrieve添加user-agent

http://www.crifan.com/use_python_urllib-

 

urlretrieve_download_picture_speed_too_slow_add_user_agent_for_urlretrieve/

点击复制链接 与好友分享!回本站首页
相关TAG标签 爬虫 心得
上一篇:python抓取bing主页背景图片
下一篇:Python抓取花瓣网图片脚本
相关文章
图文推荐
文章
推荐
点击排行

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站