python爬虫--基础知识

Python开发简单爬虫

         源码网址:  http://download.csdn.net/detail/hanchaobiao/9860671

一、爬虫的简介及爬虫技术价值

       1.什么是爬虫

         一段自动抓取互联网信息的程序,可以从一个URL出发,访问它所关联的URL,提取我们所需要的数据。也就是说爬虫是自动访问互联网并提取数据的程序。


           

         2.爬虫的价值

     将互联网上的数据为我所用,开发出属于自己的网站或APP

简单的网络爬虫流程架 

  爬虫调度端:用来启动、执行、停止爬虫,或者监视爬虫中的运行情况
  在爬虫程序中有三个模块URL管理器:对将要爬取的URL和已经爬取过的URL这两个数据的管理
  网页下载器:将URL管理器里提供的一个URL对应的网页下载下来,存储为一个字符串,这个字符串会传送给网页解析器进行解析
  网页解析器:一方面会解析出有价值的数据,另一方面,由于每一个页面都有很多指向其它页面的网页,这些URL被解析出来之后,可以补充进URL管理 器
  这三部门就组成了一个简单的爬虫架构,这个架构就能将互联网中所有的网页抓取下来


   动态执行流程


     

三、URL管理器及三种实现方式

    防止重复抓取和循环抓取,最严重情况两个URL相互指向就会形成死循环

    

    三种实现方式

    Python内存set集合:set集合支持去重的作用

    Mysqlurl(访问路径)is_crawled(是否访问)

    Redis:使用Redis性能最好,且Redis中也有set类型,可以去重。不懂得同学可以看下Redis的介绍

                   

四、网页下载器和urlib模块 

   本文使用urllib实现

   urllib2python自带的模块,不需要下载。
   urllib2python3.x中被改为urllib.request

           

         三种实现方式

            方法一:

[python]  view plain  copy
  1. #引入模块  
  2. from urllib import request  
  3. url = "http://www.baidu.com"  
  4.   
  5. #第一种下载网页的方法  
  6. print("第一种方法:")  
  7. #request = urllib.urlopen(url)  2.x  
  8. response1 = request.urlopen(url)  
  9. print("状态码:",response1.getcode())  
  10. #获取网页内容  
  11. html = response1.read()  
  12. #设置编码格式  
  13. print(html.decode("utf8"))  
  14. #关闭response1  
  15. response1.close()  
   

   方法二:

[python]  view plain  copy
  1. print("第二种:")  
  2. request2 = request.Request(url)  
  3. request2.add_header('user-agent','Mozilla/5.0')  
  4. response2 = request.urlopen(request2)  
  5. print("状态码:",response2.getcode())  
  6. #获取网页内容  
  7. htm2 = response2.read()  
  8. #调整格式  
  9. print(htm2.decode("utf8"))  
  10. #关闭response1  
  11. response2.close()  

   方法三:使用cookie

[html]  view plain  copy
  1. <span style="font-size:12px;">#第三种方法 使用cookie获取  
  2. import http.cookiejar  
  3. cookie = http.cookiejar.LWPCookieJar()  
  4. opener = request.build_opener(request.HTTPCookieProcessor(cookie))  
  5. request.install_opener(opener)  
  6. response3 = request.urlopen(url)  
  7. print(cookie)  
  8. html3 = response3.read()  
  9. #将内容格式排列  
  10. print(html3.decode("utf8"))  
  11. response3.close()</span>  

五、网页解析器和BeautifulSoup第三方模块

           

             


             测试是否安装bs4

        

[python]  view plain  copy
  1. import bs4  
  2. print(bs4)  
  3.   
  4. 打印结果:<module 'bs4' from 'D:\\app\\Python\\Anaconda\\lib\\site-packages\\bs4\\__init__.py'>  
  5. 则安装成功  

         Beautiful Soup 相比其他的html解析有个非常重要的优势。html会被拆解为对象处理。全篇转化为字典和数组。

         相比正则解析的爬虫,省略了学习正则的高成本,本文使用python3.x系统自带不需要安装。

         使用案例:http://blog.csdn.net/watsy/article/details/14161201


           方法介绍




     实例测试

                html采用官方案例


[python]  view plain  copy
  1. #引用模块  
  2. from bs4 import BeautifulSoup  
  3.   
  4. html_doc = """   
  5. <html><head><title>The Dormouse's story</title></head>   
  6. <body>   
  7. <p class="title"><b>The Dormouse's story</b></p>   
  8.  
  9. <p class="story">Once upon a time there were three little sisters; and their names were   
  10. <a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>,   
  11. <a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and   
  12. <a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;   
  13. and they lived at the bottom of a well.</p>   
  14. <p class="story">...</p>   
  15. """  

      获取所有的链接

[python]  view plain  copy
  1. print("获取所有的链接")  
  2. links = soup.find_all('a')  #a标签  
  3. for link in links:  
  4.     print(link.name,link['href'],link.get_text())  

[python]  view plain  copy
  1. #获取href=http://example.com/lacie的链接  
  2. print("获取lacie链接")  
  3. link1 = soup.find('a',href="http://example.com/lacie")  
  4. print(link1.name,link1['href'],link1.get_text())  


[python]  view plain  copy
  1. print("正则匹配 href中带有“ill”的")  
  2. import re #导入re包  
  3. link2 = soup.find('a',href=re.compile(r"ill"))  
  4. print(link2.name,link2['href'],link2.get_text())  

[python]  view plain  copy
  1. print("获取p段落文字")  
  2. link3 = soup.find('p',class_="title"#class是关键字 需要加_  
  3. print(link3.name,link3.get_text())  

六、爬虫开发实例(目标爬虫百度百科)

           

            入口:http://baike.baidu.com/item/Python

           分析URL格式:防止访问无用路径 http://baike.baidu.com/item/{标题}

           数据:抓取百度百科相关Python词条网页的标题和简介

                       通过审查元素得标题元素为 :class="lemmaWgt-lemmaTitle-title"

                       简介元素为:class="lemma-summary"

            页面编码:UTF-8

            作为定向爬虫网站要根据爬虫的内容升级而升级如运行出错可能为百度百科升级,此时则需要重新分析目标

            代码集注释:

            创建spider_main.py

[python]  view plain  copy
  1. #创建类  
  2. from imooc.baike_spider import url_manager,html_downloader,html_output,html_parser  
  3. class spiderMain:  
  4.     #构造函数 初始化  
  5.     def __init__(self):  
  6.         #实例化需引用的对象  
  7.         self.urls = url_manager.UrlManager()  
  8.         self.downloader = html_downloader.HtmlDownLoader()  
  9.         self.output = html_output.HtmlOutPut()  
  10.         self.parser = html_parser.HtmlParser()  
  11.   
  12.     def craw(self,root_url):  
  13.         #添加一个到url中  
  14.         self.urls.add_new_url(root_url)  
  15.         count = 1  
  16.         while self.urls.has_new_url():  
  17.             try:  
  18.                 new_url = self.urls.get_new_url()  
  19.                 print('craw %d : %s' %(count,new_url))  
  20.                 #下载  
  21.                 html_context = self.downloader.downloade(new_url)  
  22.                 new_urls,new_data = self.parser.parse(new_url,html_context)  
  23.                 print(new_urls)  
  24.                 self.urls.add_new_urls(new_urls)  
  25.                 self.output.collect_data(new_data)  
  26.                 #爬一千个界面  
  27.                 if(count==1000):  
  28.                     break  
  29.                 count+=1  
  30.             except:  
  31.                 print("craw faile")  
  32.         self.output.output_html()  
  33.   
  34.   
  35. #创建main方法  
  36. if __name__ == "__main__":  
  37.     root_url = "http://baike.baidu.com/item/Python"  
  38.     obj_spider = spiderMain()  
  39.     obj_spider.craw(root_url)  

     创建url_manager.py

[python]  view plain  copy
  1. class UrlManager:  
  2.     'url管理类'  
  3.     #构造函数初始化set集合  
  4.     def __init__(self):  
  5.         self.new_urls = set() #待爬取的url  
  6.         self.old_urls = set() #已爬取的url  
  7.   
  8.     #向管理器中添加一个新的url  
  9.     def add_new_url(self,root_url):  
  10.         if(root_url is None):  
  11.             return  
  12.         if(root_url not in self.new_urls and root_url not in self.old_urls):  
  13.             #既不在待爬取的url也不在已爬取的url中,是一个全新的url,因此将其添加到new_urls  
  14.             self.new_urls.add(root_url)  
  15.   
  16.     # 向管理器中添加批量新的url  
  17.     def add_new_urls(self,urls):  
  18.         if(urls is None or len(urls) == 0):  
  19.             return  
  20.         for url in urls:  
  21.             self.add_new_url(url) #调用add_new_url()  
  22.   
  23.     #判断是否有新的待爬取的url  
  24.     def has_new_url(self):  
  25.         return len(self.new_urls) != 0  
  26.     #获取一个待爬取的url  
  27.     def get_new_url(self):  
  28.         new_url = self.new_urls.pop()  
  29.         self.old_urls.add(new_url)  
  30.         return new_url  

    创建html_downloader.py

 
[python]  view plain  copy
  1. <span style="font-size:12px;">from urllib import request  
  2. from urllib.parse import quote  
  3. import string  
  4. class HtmlDownLoader:  
  5.     '下载页面内容'  
  6.     def downloade(self,new_url):  
  7.         if(new_url is None):  
  8.             return None  
  9.         #解决请求路径中含义中文或特殊字符  
  10.         url_ = quote(new_url, safe=string.printable);  
  11.         response = request.urlopen(url_)  
  12.         if(response.getcode()!=200):  
  13.             return None #请求失败  
  14.         html = response.read()  
  15.         return html.decode("utf8")</span>  

       创建html_parser.py

[python]  view plain  copy
  1. from bs4 import BeautifulSoup  
  2. import re  
  3. from urllib import parse  
  4. class HtmlParser:  
  5.     #page_url 基本url 需拼接部分  
  6.     def _get_new_urls(self,page_url,soup):  
  7.         new_urls = set()  
  8.         #匹配 /item/%E8%87%AA%E7%94%B1%E8%BD%AF%E4%BB%B6  
  9.         links = soup.find_all('a',href=re.compile(r'/item/\w+'))  
  10.         for link in links:  
  11.             new_url = link["href"]  
  12.             #例如page_url=http://baike.baidu.com/item/Python new_url=/item/史记·2016?fr=navbar  
  13.             #则使用parse.urljoin(page_url,new_url)后 new_full_url = http://baike.baidu.com/item/史记·2016?fr=navbar  
  14.             new_full_url = parse.urljoin(page_url,new_url)  
  15.             new_urls.add(new_full_url)  
  16.         return new_urls  
  17.   
  18.     def _get_new_data(self,page_url,soup):  
  19.         #<dd class="lemmaWgt-lemmaTitle-title"> <h1>Python</h1>  
  20.         red_data = {}  
  21.         red_data['url'] = page_url  
  22.         title_node = soup.find('dd',class_="lemmaWgt-lemmaTitle-title").find('h1'#获取标题内容  
  23.         red_data['title'] = title_node.get_text()  
  24.         #<div class="lemma-summary" label-module="lemmaSummary">  
  25.         summary_node = soup.find('div',class_="lemma-summary")  
  26.         red_data['summary'] = summary_node.get_text()  
  27.         return red_data  
  28.   
  29.   
  30.   
  31.     #new_url路径 html_context界面内容  
  32.     def parse(self,page_url, html_context):  
  33.         if(page_url is None or html_context is None):  
  34.             return  
  35.         #python3缺省的编码是unicode, 再在from_encoding设置为utf8, 会被忽视掉,去掉【from_encoding = "utf-8"】这一个好了  
  36.         soup = BeautifulSoup(html_context, "html.parser")  
  37.         new_urls = self._get_new_urls(page_url, soup)  
  38.         new_data = self._get_new_data(page_url, soup)  
  39.         return new_urls,new_data  
       创建html_output.py

[python]  view plain  copy
  1. class HtmlOutPut:  
  2.     def __init__(self):  
  3.         self.datas = [] #存放搜集的数据  
  4.     def collect_data(self,new_data):  
  5.         if(new_data is None):  
  6.             return  
  7.         self.datas.append(new_data)  
  8.   
  9.     def output_html(self):  
  10.         fout = open('output.html','w',encoding='utf8')  #写入文件 防止中文乱码  
  11.         fout.write('<html>\n')  
  12.         fout.write('<body>\n')  
  13.         fout.write('<table>\n')  
  14.         for data in self.datas:  
  15.             fout.write('<tr>\n')  
  16.             fout.write('<td>%s</td>\n'%data['url'])  
  17.             fout.write('<td>%s</td>\n'%data['title'])  
  18.             fout.write('<td>%s</td>\n'%data['summary'])  
  19.             fout.write('</tr>\n')  
  20.         fout.write('</table>\n')  
  21.         fout.write('</body>\n')  
  22.         fout.write('</html>\n')  
  23.         fout.close()  

视频网站:http://www.imooc.com/learn/563

源码网址:http://download.csdn.net/detail/hanchaobiao/9860671

转载自https://blog.csdn.net/hanchaobiao/article/details/72860523


                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值