【Python爬虫】爬虫的基本修养

爬虫的基本修养

一、什么是爬虫?

#1、什么是互联网?
    互联网是由网络设备(网线,路由器,交换机,防火墙等等)和一台台计算机连接而成,像一张网一样。

#2、互联网建立的目的?
    互联网的核心价值在于数据的共享/传递:数据是存放于一台台计算机上的,而将计算机互联到一起的目的就是为了能够方便彼此之间的数据共享/传递,否则你只能拿U盘去别人的计算机上拷贝数据了。

#3、什么是上网?爬虫要做的是什么?
    我们所谓的上网便是由用户端计算机发送请求给目标计算机,将目标计算机的数据下载到本地的过程。
    #3.1 只不过,用户获取网络数据的方式是:
      浏览器提交请求->下载网页代码->解析/渲染成页面。

    #3.2 而爬虫程序要做的就是:
      模拟浏览器发送请求->下载网页代码->只提取有用的数据->存放于数据库或文件中
 
    #3.1与3.2的区别在于:
      我们的爬虫程序只提取网页代码中对我们有用的数据

#4、总结爬虫
    #4.1 爬虫的比喻:
      如果我们把互联网比作一张大的蜘蛛网,那一台计算机上的数据便是蜘蛛网上的一个猎物,而爬虫程序就是一只小蜘蛛,沿着蜘蛛网抓取自己想要的猎物/数据

    #4.2 爬虫的定义:
      向网站发起请求,获取资源后分析并提取有用数据的程序 

    #4.3 爬虫的价值:
      互联网中最有价值的便是数据,比如天猫商城的商品信息,链家网的租房信息,雪球网的证券投资信息等等,这些数据都代表了各个行业的真金白银,
可以说,谁掌握了行业内的第一手数据,谁就成了整个行业的主宰,如果把整个互联网的数据比喻为一座宝藏,那我们的爬虫课程就是来教大家如何来高效地挖掘这些宝藏,
掌握了爬虫技能,你就成了所有互联网信息公司幕后的老板,换言之,它们都在免费为你提供有价值的数据。

二、爬虫的基本流程

#1、发起请求requests.get()/requests.post()
使用http库向目标站点发起请求,即发送一个Request
Request包含:请求头、请求体等

#2、获取响应内容response.text/response.content
如果服务器能正常响应,则会得到一个Response
Response包含:html,json,图片,视频等

#3、解析内容
解析html数据:正则表达式,第三方解析库如Beautifulsoup,pyquery等
解析json数据:json模块
解析二进制数据:以b的方式写入文件

#4、保存数据
数据库
文件

三、请求与响应

#http协议:http://www.cnblogs.com/haiyan123/p/7298967.html

#Request:用户将自己的信息通过浏览器(socket client)发送给服务器(socket server)

#Response:服务器接收请求,分析用户发来的请求信息,然后返回数据(返回的数据中可能包含其他链接,如:图片,js,css等)

#ps:浏览器在接收Response后,会解析其内容来显示给用户,而爬虫程序在模拟浏览器发送请求然后接收Response后,是要提取其中的有用数据。

四、requests

#1、请求方式:
    常用的请求方式:GET,POST
    其他请求方式:HEAD,PUT,DELETE,OPTHONS

    ps:用浏览器演示get与post的区别,(用登录演示post)

    post与get请求最终都会拼接成这种形式:k1=xxx&k2=yyy&k3=zzz
    post请求的参数放在请求体内:
        可用浏览器查看,存放于form data内
    get请求的参数直接放在url后

#2、请求url
    url全称统一资源定位符,如一个网页文档,一张图片
    一个视频等都可以用url唯一来确定

    url编码
    https://www.baidu.com/s?wd=图片
    图片会被编码(看示例代码)


    网页的加载过程是:
    加载一个网页,通常都是先加载document文档,
    在解析document文档的时候,遇到链接,则针对超链接发起下载图片的请求

#3、请求头
    User-agent:告诉它这是浏览器发过来的请求(请求头中如果没有user-agent客户端配置,服务端可能将你当做一个非法用户)务必加上
    host
    cookies:cookie用来保存登录信息
    Referer:上一次的跳转路径


    一般做爬虫都会加上请求头


#4、请求体
    如果是get方式,请求体没有内容
    如果是post方式,请求体是format data

    ps:
    1、登录窗口,文件上传等,信息都会被附加到请求体内
    2、登录,输入错误的用户名密码,然后提交,就可以看到post,正确登录后页面通常会跳转,无法捕捉到post
import requests

kwords = input("请输入关键字:>>").strip()
response = requests.get(
    "https://www.baidu.com/s?",
    # 请求的url,当你在百度输入中文的时候,你把url拿下来会变成下面的这样格式的url
    # https://www.baidu.com/s?wd=%E4%BD%9F%E4%B8%BD%E5%A8%85&rsv_spt=1&rsv_iqid=0xaf1eef80000239c9&issp=1&f=8&rsv_bp=1&rsv_idx=2&ie=utf-8&tn=baiduhome_pg&rsv_enter=1&rsv_sug3=10&rsv_sug1=7&rsv_sug7=101
    params={
        "wd": kwords,
    },
    # 请求头
    headers={
        "User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.108 Safari/537.36",
    },
)
html_all = response.text
print(response.status_code)
print(html_all)
with open("b.html", "w", encoding="utf-8") as f:
    f.write(response.text)
实例代码一
kwords = input("请输入关键字:>>").strip()
response = requests.get(
    "https://www.baidu.com/s?",
    # 请求的url,当你在百度输入中文的时候,你把url拿下来会变成下面的这样格式的url
    params={
        "wd":kwords,
        'pn':20
    },
    # 请求头
    headers={
        "User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.108 Safari/537.36",
    },
)
with open("b.html","w",encoding="utf-8") as f:
    f.write(response.text)
# print(response.status_code)
示例代码二(和上面的结果是一样的)

五、response

#1、http响应状态status_code
    200:代表成功
    301:代表跳转
    404:文件不存在
    403:权限
    502:服务器错误

#2、Respone header
    Location:跳转
    set-cookie:可能有多个,是来告诉浏览器,把cookie保存下来
    
#3、preview就是网页源代码
    最主要的部分,包含了请求资源的内容
    如网页html,图片
    二进制数据等

六、总结

#1、总结爬虫流程:
    爬取--->解析--->存储

#2、爬虫所需工具:
    请求库:requests,selenium
    解析库:正则,beautifulsoup,pyquery
    存储库:文件,MySQL,Mongodb,Redis

#3、爬虫常用框架:
    scrapy

七、实战案例---校花网视频

import requests,time,hashlib,random,os
from bs4 import BeautifulSoup
from threading import Thread

header = {"Cookie": "Hm_lvt_0dfa94cc970f5368ddbe743609970944=1559176088; bdshare_firstime=1559176207272",
          "Host": "www.xiaohuar.com",
          "Referer": "http://www.xiaohuar.com/",
          "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3472.3 Safari/537.36"
          }

class XiaoHuaR(Thread):
    def __init__(self,filepath,url):
        super().__init__()
        self.filepath = filepath
        self.url = url

    def page_html(self,url):
        try:
            response = requests.get(url,headers = header)
            if response.status_code == 200:
                return response
        except Exception as e:
            print(e)
            pass

    def parse_all_items(self,url):
        html = self.page_html(url).text
        soup = BeautifulSoup(html,"lxml")
        items_list = soup.find(id="images").find_all(attrs={"class":"items"})
        items = []
        for item in items_list:
            try:
                page_url = item.a.attrs["href"]
                items.append(page_url)
            except:
                continue
        return items

    def get_movie_info(self,url):
        try:
            html = self.page_html(url).text
            soup = BeautifulSoup(html,"lxml")
            movie_url = soup.find(id="player").find(id="media").find('source').attrs["src"]
            movie_title = soup.find(attrs={"class":"contentinfo"}).find("h1").text+"."+movie_url.split(".")[-1]
            if not movie_title:
                md5 = hashlib.md5()
                md5.update(str(time.time()).encode('utf8'))
                movie_title = md5.hexdigest()
            return movie_title,movie_url
        except Exception as e:
            return None

    def saveTofile(self,path,url):
        byteContent = self.page_html(url).content
        with open(path,'wb') as f:
            f.write(byteContent)
            print("%s --->下载成功"%path)

    def run(self):
        items_list = self.parse_all_items(self.url)
        for item in items_list:
            path = self.filepath
            movie_info = self.get_movie_info(item)
            if movie_info:
                path = path + movie_info[0]
                print(movie_info)
                print(path)
                try:
                    self.saveTofile(path,movie_info[1])
                    time.sleep(random.randint(1,3))
                except:
                    continue


if __name__ == '__main__':
    if not os.path.exists("校花网小视频"):
        os.makedirs("校花网小视频")
    filepath = "校花网小视频\"
    for i in range(10):
        url = "http://www.xiaohuar.com/list-3-{page_num}.html".format(page_num=i)
        xiaohua  = XiaoHuaR(filepath,url)
        xiaohua.start()

    print(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>主")
简单的多线程爬校花网小视频
原文地址:https://www.cnblogs.com/XJT2018/p/10949492.html