python 爬虫入门(二) 爬取简单网页并保存到本地

import re

from urllib.request import Request, urlopen

#爬虫基本的三个步骤:1.向页面发送请求, 获取源代码(都是静态页面的代码);2, 利用正则匹配数据;3 .保存到数据库


class DataParserTool(object):

#类中方法cls

    @classmethod

    def  parser_data(cls, data):

data_list = []
        for title, info, name, time, read_num, comment_num in data:
            title = title.strip() # 去除两端空格strip()切片是非常常用的处理数据的方法

            res = info.replace('
', '')  #replace把第一个参数替换成第二个参数
            res1 = res.replace('\n', '')
            info = res1.strip()

            name = name.strip()
            time = time.strip()

            data_list.append((title, info, name, time, read_num, comment_num))  #append添加注意添加的内容是元组!!
        return data_list


class CSDNSpider(object):
    """
初始化,避免干扰因素
    """
    def __init__(self, url):  #将网址传进来
        self.url = url  #同一类下加上关键字self.整个类内都可以调用
        # 设置浏览器标识,避免被识别为机器操作,不过要想真正不被发现还是远远不够的
        self.user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36"

    def get_page_code(self):
        # 创建了一个请求对象 headers类型字典参数user-agent是要传到浏览器上给浏览器看的
        request = Request(url=self.url, headers={'User-Agent': self.user_agent})

        # 发送请求urlopen关键字参数.可携带请求头给指定的URL发送请求他的参数
        try:
            response = urlopen(request)
            # 从响应对象中获取源代码字符串。加入try方法是为了捕获异常防止报错程序终止
            # response.read(): <class 'bytes'>字节类型,python3新增
            # decode(): 将bytes类型转成str类型
            # encode():  将str类型转成bytes类型
            data = response.read().decode()
        except Exception as e:
            print('请求异常')
        else:
            return data

    def parse_data_by_html(self, html):
        """
        解析Html,获取数据
        :param html: 源代码
        :return: 返回解析的数据
     正则险些在这,真正去匹配是到re.findall()时所以一定要注意findall中的两个参数
     """
        pattern = re.compile(r'<div class="list_con">.*?<a.*?>(.*?)</a>.*?<div class="summary oneline">(.*?)</div>.*?<dl class="list_userbar">.*?<dd class="name">.*?<a.*?>(.*?)</a>.*?<dd class="time">(.*?)</dd>.*?<span class="num">(.*?)</span>.*?<span class="num">(.*?)</span>', re.S)
        res = re.findall(pattern, html)

        # 处理数据
        data = DataParserTool.parser_data(res)
        return data

    def save_data_to_db(self, res):
        f = open('csdn.txt', 'w', encoding='utf-8')  #写入本地文件名csdn 类型汉字(W) 编码方式utf-8

        for title, info, name, time, read_num, comment_num in res:
            f.write(title)
            f.write('\n')   #换行
            f.write(info)
            f.write('\n')
            f.write(name)
            f.write('\n')
            f.write(time)
            f.write('\n')
            f.write(read_num)
            f.write('\n')
            f.write(comment_num)
            f.write('\n')

        f.close()

    def start_spider(self):
        html = self.get_page_code()
        data = self.parse_data_by_html(html)
        self.save_data_to_db(data)


#程序在本页面将此处开始运行(main)
if __name__ == "__main__":
    csdn = CSDNSpider('https://blog.csdn.net/')  #初始程序即将访问的网页调用类名为CSDNSpider的类进行操作
    csdn.start_spider()




#程序是从 __name__ =="__main__"开始运行的,这是一个开始标志,不加该标志每次打开运行脚本所有的函数都会被调用一遍,容易出错.
重点!!!滤清楚程序运行顺序和参数的传递,以及各个函数对参数的操作!!(要么死,要么学) 


展开阅读全文

没有更多推荐了,返回首页