专栏首页叁金大数据自学Python十一 Python爬虫总结

自学Python十一 Python爬虫总结

  通过几天的学习与尝试逐渐对python爬虫有了一些小小的心得,我们渐渐发现他们有很多共性,总是要去获取一系列的链接,读取网页代码,获取所需内容然后重复上面的工作,当自己运用的越来越熟练之后我们就会尝试着去总结一下爬虫的共性,试着去写个helper类以避免重复性劳动。

  参考:用python爬虫抓站的一些技巧总结 zz

  1.访问网站 #最简单的得到网页代码的方法

1 import urllib2
2 response = urllib2.urlopen("http://www.xx.com")
3 print response.read()

  2.伪装成浏览器(User-Agent,Referer等) #为了不被服务器禁止访问所以还是伪装成浏览器比较好

1 headers = {
2     'User-Agent': 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)',
3     'Referer':'http://www.xx.com/xx',
4     'Accept':'application/javascript, */*;q=0.8'
5 }
6 response = urllib2.Request(url = "http://www.xx.com",data = None,headers = headers)

  3.Post数据转码

1 import urllib,urllib2
2 values = {
3     'username':'xxx',
4     'password':'xxx',
5     'key':'xxx'
6 }
7 postdata = urllib.urlencode(values)
8 response = urllib2.Request(url,data = postdata)

  4.Cookies

1 import urllib2,cookielib
2 cookie_handler = urllib2.HTTPCookieProcessor(cookielib.CookieJar())
3 opener = urllib2.build_opener(cookie_handler)
4 urllib2.install_opener(opener)
5 response = urllib2.urlopen(url)

  5.代理服务器 #重复多次访问同一网址 结果被封了ip或限制了访问次数

1 import urllib2
2 proxy_handler = urllib2.ProxyHandler({"http" : '42.121.6.80:8080'})
3 opener = urllib2.build_opener(proxy_handler)
4 urllib2.install_opener(opener)
5 response = urllib2.urlopen(url)

  问:如果想cookie和proxy一起用怎么办?

  答:urllib2.build_opener可以放多个参数,即handler 如:BaseHandler,ProxyHandler,HTTPHandler,FileHandler,FTPHandler,CacheFTPHandler等等等等

  6.gzip #现在普遍支持gzip压缩,我们默认获取压缩后的网页,大大提高了抓取网页的效率,减少了带宽负荷。

1 import urllib2,zlib
2 req = urllib2.Request(url)
3 req.add_header('Accept-encoding', 'gzip')
4 response = urllib2.urlopen(req, timeout=120)
5 html = response.read()
6 gzipped = response.headers.get('Content-Encoding')
7 if gzipped:
8     html = zlib.decompress(html, 16+zlib.MAX_WBITS)

  7.其他

  设置线程栈大小:栈大小显著影响python的内存占用,方法如下:

 1 from threading import stack_size 2 stack_size(32768*16)

  设置超时

1 import socket
2 socket.setdefaulttimeout(10) #设置10秒后连接超时

  失败后重试

 1 def get(self,req,retries=3):
 2     try:
 3         response = self.opener.open(req)
 4         data = response.read()
 5     except Exception , what:
 6         print what,req
 7         if retries>0:
 8             return self.get(req,retries-1)
 9         else:
10             print 'GET Failed',req
11             return ''
12     return data

  根据以上内容,我们可以写出便于配置解决重复性工作的自己的helper类:

 1 # -*- coding: utf-8 -*-
 2 import cookielib, urllib, urllib2, socket
 3 import zlib,StringIO
 4 class HttpClient:
 5   __cookie = cookielib.CookieJar()
 6   #代理设置,需要时添加(后续设置为多代理切换)
 7   #__proxy_handler = urllib2.ProxyHandler({"http" : '42.121.6.80:8080'})
 8   __req = urllib2.build_opener(urllib2.HTTPCookieProcessor(__cookie))#,__proxy_handler)
 9   __req.addheaders = [
10     ('Accept', 'application/javascript, */*;q=0.8'),
11     ('User-Agent', 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)')
12   ]
13   urllib2.install_opener(__req)
14 
15   def Get(self, url, refer=None,retries=3):
16     try:
17       req = urllib2.Request(url)
18       req.add_header('Accept-encoding', 'gzip')
19       if not (refer is None):
20         req.add_header('Referer', refer)
21       response = urllib2.urlopen(req, timeout=120)
22       html = response.read()
23       gzipped = response.headers.get('Content-Encoding')
24       if gzipped:
25           html = zlib.decompress(html, 16+zlib.MAX_WBITS)
26       return html
27     except Exception,what:
28         print what
29         if retries>0:
30             return self.Get(url,refer,retries-1)
31         else:
32             print "Get Failed",url
33             return ''
34     #except urllib2.HTTPError, e:
35     #  return e.read()
36     #except socket.timeout, e:
37     #  return ''
38     #except socket.error, e:
39     #  return ''
40 
41   def Post(self, url, data, refer=None):
42     try:
43       req = urllib2.Request(url, urllib.urlencode(data))
44       #req = urllib2.Request(url,data)
45       if not (refer is None):
46         req.add_header('Referer', refer)
47       return urllib2.urlopen(req, timeout=120).read()
48     except urllib2.HTTPError, e:
49       return e.read()
50     except socket.timeout, e:
51       return ''
52     except socket.error, e:
53       return ''
54 
55   def Download(self, url, file):
56     output = open(file, 'wb')
57     output.write(urllib2.urlopen(url).read())
58     output.close()
59 
60   def getCookie(self, key):
61     for c in self.__cookie:
62       if c.name == key:
63         return c.value
64     return ''
65 
66   def setCookie(self, key, val, domain):
67     ck = cookielib.Cookie(version=0, name=key, value=val, port=None, port_specified=False, domain=domain, domain_specified=False, domain_initial_dot=False, path='/', path_specified=True, secure=False, expires=None, discard=True, comment=None, comment_url=None, rest={'HttpOnly': None}, rfc2109=False)
68     self.__cookie.set_cookie(ck)

  至于多线程就参考网上找的这段代码好了,还支持并发。。。

 1 from threading import Thread
 2 from Queue import Queue
 3 from time import sleep
 4 #q是任务队列
 5 #NUM是并发线程总数
 6 #JOBS是有多少任务
 7 q = Queue()
 8 NUM = 2
 9 JOBS = 10
10 #具体的处理函数,负责处理单个任务
11 def do_somthing_using(arguments):
12     print arguments
13 #这个是工作进程,负责不断从队列取数据并处理
14 def working():
15     while True:
16         arguments = q.get()
17         do_somthing_using(arguments)
18         sleep(1)
19         q.task_done()
20 #fork NUM个线程等待队列
21 for i in range(NUM):
22     t = Thread(target=working)
23     t.setDaemon(True)
24     t.start()
25 #把JOBS排入队列
26 for i in range(JOBS):
27     q.put(i)
28 #等待所有JOBS完成
29 q.join()

   爬虫就靠一段落吧,更深入的爬虫框架以及html解析库暂时放一放,让我考虑考虑接下来的内容,是pygame还是django!

  爬虫demo的github地址(刚学着玩git ):http://git.oschina.net/tabei/Python_spider

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • WPF播放器

    最近由于工作需要,需要做一个播放软件,在网上参考了很多例子,园子里有很多代码。其中最多的就是wpf自带的MediaElement控件,或者VLC视频播放器。

    叁金
  • 自学Python四 爬虫基础知识储备

      首先,推荐两个关于python爬虫不错的博客:Python爬虫入门教程专栏   和 Python爬虫学习系列教程 。写的都非常不错,我学习到了很多东西!在此...

    叁金
  • 自学Python二 Python中的屠龙刀(续)

    秉承着一切皆对象的理念,函数作为对象,可以为其赋值新的对象名,也可以作为参数传递给其他函数!

    叁金
  • Spring 中的属性赋值

    如果使用配置文件中的值,需要指定配置文件的位置,使用 context:property-placeholder 标签。

    wsuo
  • 存储过程和触发器的应用

    L宝宝聊IT
  • YOLOv4损失函数全面解析

    转载于:周威@知乎,https://zhuanlan.zhihu.com/p/159209199

    计算机视觉联盟
  • 日志分析实战之清洗日志小实例6:获取uri点击量排序并得到最高的url

    问题导读 1.读取日志的过程中,发生异常本文是如何解决的? 2.读取后,如何过滤异常的记录? 3.如何实现统计点击最高的记录? 日志分析实战之清洗日志...

    用户1410343
  • 浅谈拒绝服务攻击的原理与防御(6):拒绝服务攻击的防御

    0×01前言 DDOS攻击是每个需要对外提供服务的公司最大的威胁之一,尤其是新兴的互联网公司与电信运行商对此尤其看重,每个公司的网络安全组都必须具备一定的防御D...

    FB客服
  • SQL 基础--> 视图(CREATE VIEW)

    视图来源于表,所有对视图数据的修改最终都会被反映到视图的基表中,这些修改必须服从基表的完整性约束,并同样会触发定义

    Leshami
  • 7 Papers & Radios | 超图表示学习新框架HNHN;GNN的泛化与表示极限

    论文 1:Implicit Neural Representations with Periodic Activation Functions

    机器之心

扫码关注云+社区

领取腾讯云代金券