史上最最最最最最最最全Python爬虫总结

Posted python6359

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了史上最最最最最最最最全Python爬虫总结相关的知识,希望对你有一定的参考价值。

(1)普通的内容爬取
(2)保存爬取的图片/视频和文件和网页
(3)普通模拟登录
(4)处理验证码登录
(5)爬取js网站
(6)全网爬虫
(7)某个网站的站内所有目录爬虫
(8)多线程 
(9)爬虫框架Scrapy   

一,普通的内容爬取 

 1 #coding=utf-8
 2 #Python学习交流群:548377875
 3 import urllib  
 4 import urllib2  
 5 url = http://www.dataanswer.top  
 6 headers = { 
 7     Host:www.dataanswer.top,
 8     User-Agent:Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:31.0) Gecko/20100101 Firefox/31.0,
 9     #‘Accept‘:‘application/json, text/javascript, */*; q=0.01‘,
10     #‘Accept-Language‘:‘zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3‘,
11     #‘Accept-Encoding‘:‘gzip,deflate‘,
12     #‘Referer‘:‘http://www.dataanswer.top‘
13 }   
14 request = urllib2.Request(url,headers=headers)  
15 response = urllib2.urlopen(request)  
16 page = response.read()
17 print page

二,保存爬取的图片/视频和文件和网页
#图片/视频和文件和网页的地址抓取下来后,利用模块urllib里的urlretrieve()方法下载下来:

 1 #coding=utf-8
 2 import urllib  
 3 import urllib2  
 4 import os
 5 def getPage(url):     
 6     request = urllib2.Request(url)  
 7         response = urllib2.urlopen(request)  
 8         return response.read()  
 9  
10  
11 url=http://www.dataanswer.top/  
12 result=getPage(url)  
13 file_name=test.doc
14 file_path=doc
15 if os.path.exists(file_path) == False:
16     os.makedirs(file_path)
17 local=os.path.join(file_path,file_name)
18 f = open(local,"w+")  
19 f.write(result) 
20 f.close()
21  
22  
23 #coding=utf-8
24 import urllib  
25 import urllib2  
26 import os
27 def getPage(url):     
28     request = urllib2.Request(url)  
29         response = urllib2.urlopen(request)  
30         return response.read()  
31  
32  
33 url=http://www.dataanswer.top/  #把该地址改成图片/文件/视频/网页的地址即可
34 result=getPage(url)  
35 file_name=test.doc
36 file_path=doc
37 if os.path.exists(file_path) == False:
38     os.makedirs(file_path)
39 local=os.path.join(file_path,file_name)
40 urllib.urlretrieve(local)

三,普通模拟登录

 1 import urllib
 2 import urllib2
 3 import cookielib
 4  
 5 filename = cookie.txt
 6 #声明一个MozillaCookieJar对象实例来保存cookie,之后写入文件
 7 cookie = cookielib.MozillaCookieJar(filename)
 8 opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookie))
 9 postdata = urllib.urlencode({
10 name:春天里,
11 pwd:1222222
12 })
13 #登录的URL
14 loginUrl = http://www.dataanswer.top/LoginService?action=tologin
15 #模拟登录,并把cookie保存到变量
16 result = opener.open(loginUrl,postdata)
17 #保存cookie到cookie.txt中
18 cookie.save(ignore_discard=True, ignore_expires=True)
19 #利用cookie请求访问另一个网址
20 gradeUrl = http://www.dataanswer.top/LoginService?action=myHome
21 #请求访问
22 result = opener.open(gradeUrl)
23 print result.read()

四,处理验证码登录
#先把验证码图片下载下来保存,再人工读入

 1 #coding=utf-8
 2 import sys, time, os, re
 3 import urllib, urllib2, cookielib
 4 loginurl = https://www.douban.com/accounts/login
 5 cookie = cookielib.CookieJar()
 6 opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookie))
 7 params = {
 8 "form_email":"13161055481",
 9 "form_password":"wwwwwww",
10 "source":"index_nav" #没有的话登录不成功
11 }
12 #从首页提交登录
13 response=opener.open(loginurl)
14 #验证成功跳转至登录页
15 print(response.geturl())
16 if response.geturl() == "https://www.douban.com/accounts/login":
17       html=response.read()
18     print(html)
19       #验证码图片地址--图片地址加密怎么办???
20       imgurl=re.search(<img id="captcha_image" src="(.+?)" alt="captcha" class="captcha_image"/>, html)
21     print(imgurl)
22       if imgurl:
23             url=imgurl.group(1)
24             #将图片保存至同目录下
25             res=urllib.urlretrieve(url,v.jpg)
26             #获取captcha-id参数
27             captcha=re.search(<input type="hidden" name="captcha-id" value="(.+?)"/>,html)
28             if captcha:
29                   vcode=raw_input(请输入图片上的验证码:)
30                   params["captcha-solution"]=vcode
31                   params["captcha-id"]=captcha.group(1)
32                   params["user_login"]="登录"
33                   #提交验证码验证
34                   response=opener.open(loginurl, urllib.urlencode(params))
35                   ‘‘‘ 登录成功跳转至首页 ‘‘‘
36                   if response.geturl() == "https://www.douban.com/":
37                     print login success ! 
38                     print 准备进行发帖
39                     addtopicurl="http://www.douban.com/group/python/new_topic"
40                     res=opener.open(addtopicurl)
41                     html=res.read()
42             else:
43                 print("Fail3")
44         else:
45             print("Fail2")
46     else:
47         print("Fail1")
48 else:
49     print("Fail0")

五,爬取js网站
#利用selenium模拟浏览器,结合html的解析

 1 #coding=utf-8
 2 #1、安装 python-pip
 3 #sudo apt-get install python-pip
 4 #2、安装selenium
 5 #sudo pip install -U selenium
 6  
 7  
 8 from selenium import webdriver
 9 driver = webdriver.Firefox() 
10 driver.get(http://www.newsmth.net/nForum/#!article/Intern/206790)
11 html=driver.page_source.encode(utf-8,ignore) #这个函数获取页面的html
12 print(html)
13 driver.close()

六,全网爬虫
#广度优先,模拟爬取队列

  1 #coding=utf-8
  2 """
  3 全网爬取所有链接,包括外链--广度优先
  4 """
  5 import urllib2
  6 import re
  7 from bs4 import BeautifulSoup
  8 import time
  9  
 10  
 11 #爬虫开始的时间
 12 t=time.time()
 13 #设置的暂停爬取条数
 14 N_STOP=10
 15  
 16  
 17 #存放已经爬取过的url
 18 CHECKED_URL=[]
 19 #存放待爬取的url
 20 CHECKING_URL=[]
 21 #存放连接失败的url
 22 FAIL_URL=[]
 23 #存放不能连接的url
 24 ERROR_URL=[]
 25 #失败后允许连接的次数
 26 RETRY=3
 27 #连接超时时间
 28 TIMEOUT=20
 29  
 30  
 31 class url_node:
 32     def __init__(self,url):
 33         """
 34         url节点初始化
 35         :param url:String 当前url
 36         """
 37         self.url=url
 38         self.content=‘‘
 39  
 40  
 41     def __is_connectable(self):
 42         """
 43         检验url是否可以连接
 44         """
 45         #在允许连接次数下连接
 46         for i in range(RETRY):
 47             try:
 48                 #打开url没有报错,则表示可连接
 49                 response=urllib2.urlopen(self.url,timeout=TIMEOUT)
 50                 return True
 51             except:
 52                 #如果在尝试允许连接次数下报错,则不可连接
 53                 if i==RETRY-1:
 54                     return False
 55  
 56  
 57     def get_next(self):
 58         """
 59         获取爬取该页中包含的其他所有的url
 60         """
 61         soup=BeautifulSoup(self.content)
 62         #******************在此处可以从网页中解析你想要的内容************************************
 63         next_urls=soup.findAll(a)
 64         if len(next_urls)!=0:
 65             for link in next_urls:
 66                 tmp_url=link.get(href)
 67                 #如果url不在爬取过的列表中也不在待爬取列表中则把其放到待爬列表中(没有确保该url有效)
 68                 if tmp_url not in CHECKED_URL and tmp_url not in CHECKING_URL:
 69                     CHECKING_URL.append(tmp_url)
 70         
 71     def run(self):
 72         if self.url:
 73             if self.__is_connectable():
 74                 try:
 75                     #获取爬取页面的所有内容
 76                     self.content=urllib2.urlopen(self.url,timeout=TIMEOUT).read()
 77                     #从该页面中获取url
 78                     self.get_next()
 79  
 80  
 81                 except:
 82                     #把连接失败的存放起来
 83                     FAIL_URL.append(self.url)
 84                     print([!]Connect Failed)
 85             else:
 86                 #把不能连接的存放起来
 87                 ERROR_URL.append(self.url)
 88         else:
 89             print("所给的初始url有问题!")            
 90  
 91  
 92 if __name__==__main__:
 93     #把初始的url放到待爬的列表中
 94     CHECKING_URL.append(http://www.36dsj.com/)
 95     #不断的从待爬的列表中获取url进行爬取
 96     ff=open("Mytest.txt",w)
 97     i=0
 98     for url in CHECKING_URL:
 99         #对该url进行爬取
100         url_node(url).run()
101         #存放已经爬取过的url
102         CHECKED_URL.append(url)    
103         #删除CHECKING_URL中已经爬取过的url
104         CHECKING_URL.remove(url)
105  
106  
107         i+=1
108         if i==N_STOP:
109             #打出停止时的url,下次可以把该url作为初始继续
110             print url
111             print("爬取过的列表长度:%d") % len(CHECKED_URL)
112             print("待爬取的列表长度:%d") % len(CHECKING_URL)
113             print("连接失败的列表长度:%d") % len(FAIL_URL)
114             print("不能连接的列表长度:%d") % len(ERROR_URL)
115             break
116     ff.close()
117     print("time:%d s") % (time.time()-t)    

七,某个网站的站内所有目录爬虫
#把缩写的站内网址还原

  1 #coding=utf-8
  2 """
  3 爬取同一个网站所有的url,不包括外链
  4 """
  5 import urllib2
  6 import re
  7 from bs4 import BeautifulSoup
  8 import time
  9  
 10 t=time.time()
 11  
 12 HOST=‘‘
 13 CHECKED_URL=[]
 14 CHECKING_URL=[]
 15 RESULT=[]
 16 RETRY=3
 17 TIMEOUT=20
 18  
 19 class url_node:
 20     def __init__(self,url):
 21         """
 22         url节点初始化
 23         :param url:String 当前url
 24         """
 25         self.url=self.handle_url(url,is_next_url=False)
 26         self.next_url=[]
 27         self.content=‘‘
 28  
 29  
 30     def handle_url(self,url,is_next_url=True):
 31         """
 32         将所有的url处理成标准形式
 33         """
 34         global CHECKED_URL
 35         global CHECKING_URL
 36  
 37         #去掉尾部的‘/’
 38         url=url[0:len(url)-1] if url.endswith(/) else url
 39  
 40         if url.find(HOST)==-1:
 41             if not url.startswith(http):
 42                 url=http://+HOST+url if url.startswith(/) else http://+HOST+/+url
 43             else:
 44                 #如果含有http说明是外链,url的host不是当前的host,返回空
 45                 return
 46         else:
 47             if not url.startswith(http):
 48                 url=http://+url
 49  
 50  
 51         if is_next_url:
 52             #下一层url放入待检测列表
 53             if url not in CHECKING_URL:
 54                 CHECKING_URL.append(url)
 55         else:
 56             #对于当前需要检测的url将参数都替换为1,然后加入规则表
 57             #参数相同类型不同的url只检测一次
 58             rule=re.compile(r=.*?&|=.*?$)
 59             result=re.sub(rule,=1&,url)
 60             if result in CHECKED_URL:
 61                 return [!] Url has checked!
 62             else:
 63                 CHECKED_URL.append(result)
 64                 RESULT.append(url)
 65         return url
 66  
 67  
 68     def __is_connectable(self):
 69         print("进入__is_connectable()函数")
 70         #检验是否可以连接
 71         retry=3
 72         timeout=2
 73         for i in range(RETRY):
 74             try:
 75                 #print("进入_..............函数")
 76                 response=urllib2.urlopen(self.url,timeout=TIMEOUT)
 77                 return True
 78             
 79             except:
 80                 if i==retry-1:
 81                     return False
 82  
 83  
 84     def get_next(self):
 85         #获取当前所有的url
 86         #print("进入get_next()函数")
 87         soup=BeautifulSoup(self.content)
 88         next_urls=soup.findAll(a)
 89         if len(next_urls)!=0:
 90             for link in next_urls:
 91                 self.handle_url(link.get(href))
 92                 #print(link.text)
 93  
 94  
 95         
 96     def run(self):
 97         #print("进入run()函数")
 98         if self.url:
 99             #print self.url
100             if self.__is_connectable():
101                 try:
102                     self.content=urllib2.urlopen(self.url,timeout=TIMEOUT).read()
103                     self.get_next()
104  
105  
106                 except:
107                     print([!]Connect Failed)
108 #处理https开头的url的类和方法
109 class Poc:
110     def run(self,url):
111         global HOST
112         global CHECKING_URL
113         url=check_url(url)
114  
115  
116         if not url.find(https):
117             HOST=url[:8]
118         else:
119             HOST=url[7:]
120  
121  
122         for url in CHECKING_URL:
123             print(url)
124             url_node(url).run()
125  
126  
127 def check_url(url):
128     url=http://+url if not url.startswith(http) else url
129     url=url[0:len(url)-1] if url.endswith(/) else url
130  
131  
132     for i in range(RETRY):
133         try:
134             response=urllib2.urlopen(url,timeout=TIMEOUT)
135             return url
136         except:
137             raise Exception("Connect error")
138  
139  
140 if __name__==__main__:
141     HOST=www.dataanswer.com
142     CHECKING_URL.append(http://www.dataanswer.com/)
143     f=open(36大数据,w)
144     for url in CHECKING_URL:
145         f.write(url+
)
146         print(url)
147         url_node(url).run()
148     print RESULT
149     print "URL num:"+str(len(RESULT))
150     print("time:%d s") % (time.time()-t)    

八,多线程
#对列和线程的结合

  1 #!/usr/bin/env python
  2 # -*- coding:utf-8 -*-
  3 """
  4 一个简单的Python爬虫, 使用了多线程, 
  5 爬取豆瓣Top前250的所有电影
  6 """
  7  
  8 import urllib2, re, string
  9 import threading, Queue, time
 10 import sys
 11  
 12 reload(sys)
 13 sys.setdefaultencoding(utf8)
 14 _DATA = []
 15 FILE_LOCK = threading.Lock()
 16 SHARE_Q = Queue.Queue()  #构造一个不限制大小的的队列
 17 _WORKER_THREAD_NUM = 3  #设置线程的个数
 18  
 19  
 20 class MyThread(threading.Thread) :
 21  
 22  
 23     def __init__(self, func) :
 24         super(MyThread, self).__init__()  #调用父类的构造函数
 25         self.func = func  #传入线程函数逻辑
 26  
 27  
 28     def run(self) :
 29         self.func()
 30  
 31  
 32 def worker() :
 33     global SHARE_Q
 34     while not SHARE_Q.empty():
 35         url = SHARE_Q.get() #获得任务
 36         my_page = get_page(url)
 37         find_title(my_page)  #获得当前页面的电影名
 38         #write_into_file(temp_data)
 39         time.sleep(1)
 40         SHARE_Q.task_done()
 41  
 42  
 43 def get_page(url) :
 44     """
 45     根据所给的url爬取网页HTML
 46     Args: 
 47         url: 表示当前要爬取页面的url
 48     Returns:
 49         返回抓取到整个页面的HTML(unicode编码)
 50     Raises:
 51         URLError:url引发的异常
 52     """
 53     try :
 54         my_page = urllib2.urlopen(url).read().decode("utf-8")
 55     except urllib2.URLError, e :
 56         if hasattr(e, "code"):
 57             print "The server couldn‘t fulfill the request."
 58             print "Error code: %s" % e.code
 59         elif hasattr(e, "reason"):
 60             print "We failed to reach a server. Please check your url and read the Reason"
 61             print "Reason: %s" % e.reason
 62     return my_page
 63  
 64  
 65 def find_title(my_page) :
 66     """
 67     通过返回的整个网页HTML, 正则匹配前100的电影名称
 68     Args:
 69         my_page: 传入页面的HTML文本用于正则匹配
 70     """
 71     temp_data = []
 72     movie_items = re.findall(r<span.*?class="title">(.*?)</span>, my_page, re.S)
 73     for index, item in enumerate(movie_items) :
 74         if item.find(" ") == -1 :
 75             #print item,
 76             temp_data.append(item)
 77     _DATA.append(temp_data)
 78  
 79 def main() :
 80     global SHARE_Q
 81     threads = []
 82     douban_url = "http://movie.douban.com/top250?start={page}&filter=&type="
 83     #向队列中放入任务, 真正使用时, 应该设置为可持续的放入任务
 84     for index in xrange(10) :   
 85         SHARE_Q.put(douban_url.format(page = index * 25))
 86     for i in xrange(_WORKER_THREAD_NUM) :
 87         thread = MyThread(worker)
 88         thread.start()  #线程开始处理任务
 89     print("第%s个线程开始工作") % i
 90         threads.append(thread)
 91     for thread in threads :
 92         thread.join()
 93     SHARE_Q.join()
 94     with open("movie.txt", "w+") as my_file :
 95         for page in _DATA :
 96             for movie_name in page:
 97                 my_file.write(movie_name + "
")
 98     print "Spider Successful!!!"
 99  
100  
101 if __name__ == __main__:
102     main()

九,爬虫框架Scrapy

items.py:用来定义需要保存的变量,其中的变量用Field来定义,有点像python的字典
pipelines.py:用来将提取出来的Item进行处理,处理过程按自己需要进行定义
spiders:定义自己的爬虫


爬虫的类型也有好几种:
  1)spider:最基本的爬虫,其他的爬虫一般是继承了该最基本的爬虫类,提供访问url,返回response的功能,会默认调用parse方法
  2)CrawlSpider:继承spider的爬虫,实际使用比较多,设定rule规则进行网页的跟进与处理, 注意点:编写爬虫的规则的时候避免使用parse名,因为这会覆盖继承的spider的的方法parse造成错误。   其中比较重要的是对Rule的规则的编写,要对具体的网页的情况进行分析。
  3)XMLFeedSpider 与 CSVFeedSpider 

(1)打开命令行,执行:scrapy startproject tutorial(项目名称)
(2)scrapy.cfg是项目的配置文件,用户自己写的spider要放在spiders目录下面
(3)解析:name属性很重要,不同spider不能使用相同的name
start_urls是spider抓取网页的起始点,可以包括多个url
parse方法是spider抓到一个网页以后默认调用的callback,避免使用这个名字来定义自己的方法。
当spider拿到url的内容以后,会调用parse方法,并且传递一个response参数给它,response包含了抓到的网页的内容,在parse方法里,你可以从抓到的网页里面解析数据。
(3)开始抓取,进入生成的项目根目录tutorial/,执行 scrapy crawl dmoz, dmoz是spider的name。
(4)保存对象:在items.py中添加一些类,这些类用来描述我们要保存的数据

from scrapy.item import Item, Field
class DmozItem(Item):
    title = Field()
    link = Field()
    desc = Field()
(5)执行scrapy crawl dmoz --set FEED_URI=items.json --set FEED_FORMAT=json后得到保存的文件
(6)让scrapy自动抓取网页上的所有链接

在parse方法里面提取我们需要的链接,然后构造一些Request对象,并且把他们返回,scrapy会自动的去抓取这些链接

 










































以上是关于史上最最最最最最最最全Python爬虫总结的主要内容,如果未能解决你的问题,请参考以下文章

springboot系列:史上最最最全springboot常用注解 | 超级详细,建议收藏

springboot系列:史上最最最全springboot常用注解 | 超级详细,建议收藏

JVM 史上最最最完整深入解析(12000 字噢)

JVM史上最最最完整深入解析(12000字噢)

华为云技术分享小白篇,认识Python最最最常用语重要的库Requests

面试官:不懂JVM ,就要30K? 史上JVM最最最完整深入解析