一、爬虫基础概念

爬虫是啥? 蜘蛛?织网?等着猎物?

1.网络爬虫:
    定义:网络蜘蛛,抓取猎物——网络数据
    作用:用Python程序模拟人去访问网站
    注意:
        爬虫并不能自己生产数据,它只是数据的搬运工
        1.有爬虫,就有反爬
            爬取
            反爬
            反反爬
            反反反爬
            反反反反爬
    目的:通过有效的大量数据分析市场走势,提供给公司作为决策的支持,或者通过大量的数据做用户画像

2.企业获取数据的方式:
    1)公司自有的数据
    2)第三方数据平台购买
        数据堂 贵阳大数据交易所
    3)爬虫爬取数据:
        市场上找不到或者要加太高,利用程序员取爬去
        爬虫工程师:
            在需要数据的时候,让他去爬
            在公司建立网站或者的闲置的时候,提供反爬措施。

3.Python做爬虫的优势
    1)python:请求模块、解析模块丰富成熟
    2)PHP:对多线程,异步执行很差
    3)Java:代码笨重,代码量特别大
    4)c/c++:如果开发完成,效率第一,但问题是,代码成形太慢了

4.爬虫的分类:
    从功能上分类
        1)功能性爬虫:抢票 刷赞 刷评论等等
        2)数据类爬虫:主要是从网站上爬取数据

    从类型分类:
        1)通过网络爬虫(搜索引擎,需要遵守robots。txt协议)
            比如:百度
            搜索引擎如何获取一个新的网站的 URL
                网站主动向搜索引擎提供(百度站长平台)
                向万网提供,让他们收录新网站
        2)聚焦网络爬虫:
            自己写的爬虫程序:面向主题爬虫 面向需求爬虫

5.爬取数据的步骤
    1)确定需要爬取的URL地址(网站)
    2)通过发送request请求来获取response相应的HTML页面
    3)提取HTML中有用的数据
    4)将提取的数据进行保存,如果页面中还有其他的URL,继续第二步

6.WEB
    GET 和 POST
        1)GET请求:查询的参数会在URL上显示出来
        2)POST:查询参数和提交数据在 from表单,不会再URL地址上显示,更安全

    URL:
        https://www.baidu.com/s?&wd=%E5%9B%BE%E7%98%87/5053.html
        协议      域名/IP地址   参数                   资源路径

    User-Agent:
        1)记录用户的浏览器、操作系统等等,为了让用户或得更好的体验感
        2)反爬虫的第一手段

二、爬虫常用模块

1)urllib.request
        第一种:urllib  和  urllib2          <——————Python2版本的
        第二种:urllib.request 把二者合并    <——————Python3版本的

        (1)常用方法:
                1.urllib.request.urlopen("URL")
                    作用:向网站发起请求并获取相应
                注意:
                    urlopen() 得到响应对象 response:bytes
                    输出时需要进行转换:response.read().decode("utf-8"):bytes —> str
    2)urllib.request.Request(url,headers={})
        功能:重构User-Agent 是爬虫和反爬虫斗争的第一步
        1.使用步骤:
            1.构建请求对象 request:Request()
            2.获取响应对象 response:urlopen(request)
            3.利用响应对象 response.read().decode("utf-8")

        2.请求对象request方法
            1.get_header("User-agent):只有U是大写
                作用:获取已有的HTTP报头信息
        3.响应对象 response
           	 (1).read():读取服务器响应的内容
             (2).getcode():
                作用:返回HTTP的的响应码
                200:成功
                4XX:服务器页面出错
                5XX:服务器奔溃
             (3).info()
                作用:返回服务器响应的报头信息

        注意:
            爬虫的基本步骤:
                1.确认爬取的url
                2.重构请求对象:User—Agent

    已知有网址如下:
        https://www.baidu.com/s?wd=%E5%9B%BE%E7%89%87
        其中,%E5%9B%BE%E7%89%87 表示 xxx 加码后的内容

    	4.urllib.parse()
       		(1).quote:对中文编码
        	(2).unquote:解码

            在系统cmd指令中依次输入:
                python
                import urllib.parse
                urllib.parse.quote("xxx")
                urllib.parse.unquote("%E9%BB%8E%E4%BA%91%E4%BA%AE")
                
    	5.urlencode(字典)  #另一种编码方式
        	wd="图片"
        	d = {'wd':wd,'pn':10}
                        0-9:第一页  10-19:第二页 ...
                   解码时会字典在其中加 &
       		d = urllib.parse.urlencode(d)

三、爬虫获取 html 训练

作业:
    	1.爬取猫眼 top100榜
        	1)程序运行,直接爬取第1页
        	2)是否继续爬取(y/n)
            	y:爬取下一页
            	n:爬取结束,谢谢使用
       		3)把每一页的内容保存到本地
            	格式:第n页.html

    	普通版 & 类版本
##普通版本
import urllib.request
import urllib.parse
page = 1
while True:
    url = "https://maoyan.com/board/4?"
    # 编码,拼接 URL
    # quote字典加码方式
    key = {'offset': 10 * (page - 1)}
    key = urllib.parse.urlencode(key)
    urls = url + key
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36"}
    request = urllib.request.Request(urls, headers=headers)
    response = urllib.request.urlopen(request)
    html = response.read().decode("utf-8")
    try:
        # 以下方式待程序执行完毕,一定会自动释放资源
        with open("./test_file/第%d页.html" %page, 'w', encoding="utf-8") as f:
            f.write(html)
            print("第%d个网页文件保存成功!" %page)
    except Exception as e:
        print("文件打开失败!")
    judge = input("爬取下一页请输入y,结束请输入n:")
    page += 1
    if judge == "y":
        pass
    elif judge == "n":
        break
    else:
        print("输入错误,请重新输入!")
#类版本
import urllib.request
import urllib.parse
class maoyan_top100:
    #爬虫初始化
    def __init__(self):
        self.url = "https://maoyan.com/board/4?"
        self.headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36"}

    def getpage(self,page):
        key = {'offset': 10 * (page - 1)}
        key = urllib.parse.urlencode(key)
        urls = self.url + key
        request = urllib.request.Request(urls, headers=self.headers)
        response = urllib.request.urlopen(request)
        html = response.read().decode("utf-8")
        return html

    def save(self,page,html):
        try:
            # 以下方式待程序执行完毕,一定会自动释放资源
            with open("./test_file/第%d页.html" % page, 'w', encoding="utf-8") as f:
                f.write(html)
                print("第%d个网页文件保存成功!" % page)
        except Exception as e:
            print("文件打开失败!")

    def mian(self):
        page = 1
        while True:
            html = self.getpage(page)
            self.save(page,html)
            judge = input("爬取下一页请输入y,结束请输入n:")
            page += 1
            if judge == "y":
                pass
            elif judge == "n":
                break
            else:
                print("输入错误,请重新输入!")

if __name__ == "__main__":
    maoyan_top100().mian()