Fork me on GitHub

爬虫实例--Python百科词条

Python最基础的应用就是爬虫。
本文是看了慕课网一个视频教程后根据该教程写的一个爬虫实例。这个教程讲的还是挺好的,建议刚开始学Python的童鞋可以看看。


目标:抓取百度百科Python词条相关词条网页——标题和简介
入口:https://baike.baidu.com/item/Python
URL格式:

 --词条页面URL:/item/... 

数据格式:

 --标题:<dd class="lemmaWgt-lemmaTitle-title"><h1>Python</h1>
 --简介:<div class="lemma-summary" label-module="lemmaSummary">

页面编码:utf-8
开发环境:

1、安装JRE环境:下载jdk-8u161-windows-x64,安装即可
2、安装Eclipse软件:从蒲公英上下载eclipse-java-oxygen-R-win32-x86_64,直接打开exe就是
3、安装Python 2.X:在官网下载Python 2.7.14,默认安装到C盘,之后配置环境变量---将“C:\Python27”、“C:\Python27\Scripts”添加到path路径,然后将python.exe改成python2.exe
4、环境配置:打开Eclipse》Windows》Preferences》Interpreters》Python Interpreter,在右侧新建,在弹出来的窗口第二个对话框选择python2.exe,一直确定就好。

在Eclipse中新建pyDev Project,命名imooc;
右键imooc,新建pyDev package,命名baike_spider;
右键baike_spider,新建pyDev module,分别命名spider_main、url_manager、html_downloader、html_parser、html_outputer。

1、调度程序:spider_main

# coding:utf-8

from baike_spider import url_manager,html_downloader,html_parser,html_outputer

class SpiderMain(object):
    def __init__(self):                                              //初始化方法
        self.urls = url_manager.UrlManager()                         //url管理器
        self.downloader = html_downloader.HtmlDownloader()           //网页下载器
        self.parser = html_parser.HtmlParser()                       //解析器
        self.outputer = html_outputer.HtmlOutputer()                 //内容输出器

    def craw(self, root_url):
        count = 1                                                    //计数器
        self.urls.add_new_url(root_url)                              //添加根网址到url管理器
        while self.urls.has_new_url():                               //开始循环
            try:
                new_url = self.urls.get_new_url()                    //取第一个url
                print 'craw %d : %s' % (count,new_url)               //输出url
                html_cont = self.downloader.download(new_url)        //下载网页内容
                new_urls,new_data = self.parser.parse(new_url,html_cont)     //获取新的url和价值数据
                self.urls.add_new_urls(new_urls)                     //添加新的url到url管理器
                self.outputer.collect_data(new_data)                 //收集价值数据

                if count == 1000:
                    break

                count = count + 1
            except:
                print 'craw failed'

        self.outputer.output_html()                                //输出数据到网页
        print 'finished!'


if __name__=="__main__":
    root_url = "https://baike.baidu.com/item/Python"               //原始根网址
    obj_spider = SpiderMain()                                      //主程序入口
    obj_spider.craw(root_url)                                      //爬虫启动

2、url管理器:url_manager

# coding:utf-8

class UrlManager(object):
    def __init__(self):                //初始化方法
        self.new_urls = set()          //未爬URL容器
        self.old_urls = set()          //已爬URL容器

    def add_new_url(self,url):          //单个URL存储方法
        if url is None:
            return

        if url not in self.new_urls and url not in self.old_urls:
            self.new_urls.add(url)

    def add_new_urls(self,urls):          //多个URL存储方法
        if urls is None or len(urls) == 0:
            return
        for url in urls:
            self.new_urls.add(url)

    def has_new_url(self):               //判断是否还有未爬URL
        return len(self.new_urls) != 0

    def get_new_url(self):               //获取一个未爬URL
        new_url = self.new_urls.pop()
        self.old_urls.add(new_url)
        return new_url

3、网页下载:html_downloader

# coding:utf-8

import urllib2

class HtmlDownloader(object):
    def download(self,url):                    //下载网页方法
        if url is None:
            return None

        response = urllib2.urlopen(url)          //请求数据

        if response.getcode() != 200:            //状态码如果等于200,说明请求成功
            return None

        return response.read()                   //读取数据

4、解释器:html_parser

# coding:utf-8

from bs4 import BeautifulSoup
import urlparse
import re

class HtmlParser(object):
    def parse(self,page_url,html_cont):               //解释器方法:page_url是网址参数,html_cont是网页内容参数
        if page_url is None or html_cont is None:
            return

        soup = BeautifulSoup(html_cont,'html.parser',from_encoding='utf-8')     //解释器对象

        new_urls = self._get_new_urls(page_url,soup)          //获取新网址,实现方法在下面
        new_data = self._get_new_data(page_url,soup)          //获取数据,实现方法在下面

        return new_urls,new_data


    def _get_new_urls(self, page_url, soup):                           //新网址获取方法,这个要根据具体网址信息来设计,不是一成不变的
        new_urls = set()          //网址容器     

        links = soup.find_all('a',href=re.compile(r"/item/"))          //获取标签为a、包含“/item/”的链接信息(这个信息事实上是残缺的)
        for link in links:                                             //这里用到正则表达式
            new_url = link['href']                                     
            new_full_url = urlparse.urljoin(page_url,new_url)          //我们这里将残缺的网址信息和网址参数合并作为新的URL
            new_urls.add(new_full_url)
        return new_urls


    def _get_new_data(self, page_url, soup):          //价值信息获取方法
        res_data = {}     //容器,字典结构

        res_data['url'] = page_url               //将网址存入数据容器

        # <dd class="lemmaWgt-lemmaTitle-title"> <h1>Python</h1>          //这是我当时查看的网页源代码的格式
        title_node = soup.find('dd',class_="lemmaWgt-lemmaTitle-title").find("h1")     //获取标题节点
        res_data['title'] = title_node.get_text()                                      //存储标题

        # <div class="lemma-summary" label-module="lemmaSummary">
        summary_node = soup.find('div',class_="lemma-summary")          //获取简介内容节点
        res_data['summary'] = summary_node.get_text()                   //存储简介信息

        return res_data

5、输出:html_outputer

# coding:utf-8

class HtmlOutputer(object):
    def __init__(self):          //初始化方法
        self.datas = []


    def collect_data(self,data):     //数据收集方法
        if data is None:
            return
        self.datas.append(data)


    def output_html(self):
        fout = open('output.html','w')     //新建一个.html文件

        fout.write("<html>")               //将爬到的内容输出为html
        fout.write("<body>")               //所以这里输出为html表格形式
        fout.write("<table>")

        for data in self.datas:
            fout.write("<tr>")
            fout.write("<td>%s</td>" % data['url'])
            fout.write("<td>%s</td>" % data['title'].encode('utf-8'))
            fout.write("<td>%s</td>" % data['summary'].encode('utf-8'))
            fout.write("</tr>")

        fout.write("</table>")
        fout.write("</body>")
        fout.write("</html>")

        fout.close()

运行spider_main,刷新baike_spider项目,会看到新生成的output.html;找到该本地文件,直接用浏览器打开,就能看到爬虫抓取的数据信息.

-------------本文结束感谢您的阅读-------------
ChengQian wechat
有问题可以通过微信一起讨论!