402-Python爬虫

Python爬虫介绍

什么是爬虫

网络爬虫:

又被称为网页蜘蛛,网络机器人,是一种按照一定的规则,自动地抓取网络信息的程序或者脚本,另外一些不常使用的名字还有蚂蚁、自动索引、模拟程序或者蠕虫。

通俗理解:

简单来讲,爬虫就是一个探测机器,它的基本操作就是模拟人的行为去各个网站溜达,点点按钮,查查数据,或者把看到的信息背回来. 就像一只虫子在一幢楼里不知疲倦地爬来爬去.

你可以简单地想象 每个爬虫都是你的「分身」。就像孙悟空拔了一撮汗毛,吹出一堆猴子一样

**百度:**其实就是利用了这种爬虫技术, 每天放出无数爬虫到各个网站,把他们的信息抓回来,然后化好淡妆排着小队等你来检索。

有了这样的特性, 对于一些自己公司数据量不足的小公司, 这个时候还想做数据分析就可以通过爬虫获取同行业的数据然后进行分析, 进而指导公司的策略指定。

爬虫的基本步骤

基本步骤:

安装requests模块

快速入门(requests三步走):

# 导入模块
import requests
# 通过requests.get()发送请求
# data保存返回的响应数据(这里的响应数据不是单纯的html,需要通过content获取html代码)
data = requests.get("http://www.baidu.com")
# 通过data.content获取html代码
data = data.content.decode("utf-8")

爬取照片

爬取照片的步骤

  1. 获取index.html代码
  2. 解析index.html代码获取图片url
  3. 通过图片url获取图片

获取index.html代码

# 通过爬虫向index.html发送请求
# requests.get(网址): 向一个网址发送请求,和在浏览器中输入网址是一样的
data = requests.get("http://127.0.0.1:8000/index.html")
# content可以把requests.get()获取的返回值中的html内容获取到
data = data.content.decode("utf-8")

解析index.html代码获取图片url

# 获取图片的请求url
def get_pic_url():
    # 通过爬虫向index.html发送请求
    # requests.get(网址): 向一个网址发送请求,和在浏览器中输入网址是一样的
    data = requests.get("http://127.0.0.1:8000/index.html")
    # content可以把requests.get()获取的返回值中的html内容获取到
    data = data.content.decode("utf-8")
    # html每一行都有"\n", 对html进行分割获得一个列表
    data = data.split("\n")
    # 创建一个列表存储所有图片的url地址(也就是图片网址)
    url_list = []
    for url in data:
        # 通过正则解析出所有的图片url
        result = re.match('.*src="(.*)" width.*', url)
        if result is not None:
            # 把解析出来的图片url添加到url_list中
            url_list.append(result.group(1))

    return url_list

通过图片url获取图片

# 把爬取到的图片保存到本地
def save_pic(url_list):
    # 通过num给照片起名字 例如:0.jpg 1.jpg 2.jpg
    num = 0
    for url in url_list:
        # 通过requests.get()获取每一张图片
        pic = requests.get(f"http://127.0.0.1:8000{url[1:]}")  # 索引为1开始切片,去掉获取的链接的第一个点
        # 创建文件保存每一张图片
        with open(f"./source/spyder/{num}.jpg", "wb") as f:
            f.write(pic.content)
            num += 1

完整代码

import requests
import re


# 获取图片的请求url
def get_pic_url():
    # 通过爬虫向index.html发送请求
    # requests.get(网址): 向一个网址发送请求,和在浏览器中输入网址是一样的
    data = requests.get("http://127.0.0.1:8000/index.html")
    # content可以把requests.get()获取的返回值中的html内容获取到
    data = data.content.decode("utf8")
    # html每一行都有"\n", 对html进行分割获得一个列表
    data = data.split("\n")
    # 创建一个列表存储所有图片的url地址(也就是图片网址)
    url_list = []
    for url in data:
        # 通过正则解析出所有的图片url
        result = re.match('.*src="(.*)" width.*', url)
        if result is not None:
            # 把解析出来的图片url添加到url_list中
            url_list.append(result.group(1))

    return url_list


# 把爬取到的图片保存到本地
def save_pic(url_list):
    # 通过num给照片起名字 例如:0.jpg 1.jpg 2.jpg
    num = 0
    for url in url_list:
        # 通过requests.get()获取每一张图片
        pic = requests.get(f"http://127.0.0.1:8000{url[1:]}")
        # 保存每一张图片
        with open(f"./source/spyder/{num}.jpg", "wb") as f:
            f.write(pic.content)
            num += 1


if __name__ == '__main__':
    url_list = get_pic_url()
    save_pic(url_list)

爬取GDP数据

zip函数的使用

zip() 函数: 用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表.

a = [1, 2, 3]
b = [4, 5, 6]
c = [4, 5, 6, 7, 8]
# 打包为元组的列表
zipped = zip(a, b)
# 注意使用的时候需要list转化
print(list(zipped))
>>> [(1, 4), (2, 5), (3, 6)]

# 元素个数与最短的列表一致
zipped = zip(a, c)
# 注意使用的时候需要list转化
print(list(zipped))
>>> [(1, 4), (2, 5), (3, 6)]

爬取GDP数据

import requests
import re

# 存储爬取到的国家的名字
country_list = []
# 存储爬取到的国家gdp的数据
gdp_list = []


# 获取gdp数据
def get_gdp_data():
    global country_list
    global gdp_list

    # 获取gdp的html数据
    data = requests.get("http://localhost:8000/gdp.html")
    # 对获取数据进行解码
    data = data.content.decode("utf8")
    # 对gdp的html数据进行按行分割
    data_list = data.split("\n")

    for i in data_list:
        # 对html进行解析获取<国家名字>
        country_result = re.match('.*<a href=""><font>(.*)</font></a>', i)
        # 匹配成功就存放到列表中
        if country_result is not None:
            country_list.append(country_result.group(1))
        # 对html进行解析获取<gdp数据>
        gdp_result = re.match(".*¥(.*)亿元", i)
        # 匹配成功就存储到列表中
        if gdp_result is not None:
            gdp_list.append(gdp_result.group(1))
    # 把两个列表融合成一个列表
    gdp_data = list(zip(country_list, gdp_list))
    print(gdp_data)


if __name__ == '__main__':
    get_gdp_data()

爬虫进阶

伪造头信息实现反反爬虫 & Xpath技术简化提取数据

import requests
from lxml import etree

headers={
'User-Agent':'Mozilla/5.0(Windows NT 10.0;Win64; x64) AppleWebKit/537.36(KHTML, Like Gecko) Chrome/101.0.0.0 Safari/537.36'
}  # 伪造浏览器的头信息

res = requests.get('http://www.splxx.cn/WarticleList.aspx?typeid=opDItqtHf7A=', headers=headers)
#把数据转换为HTML结构=>结合XPath读取
data = etree.HTML(res.text)
data = data.xpath('//div[@class="list_body"]//li/a/text()')  # 使用xpath技术读取数据,//表示从根节点开始,div[@class="list_body"]表示class为list_body的div标签,//li/a/text()表示li标签下的a标签下的text()
for row in data:
    print(row)

多任务爬虫

同时爬取gdp数据和下载图片

# 获取gdp
def get_gdp_data():
    pass


# 获取照片
def get_pic():
    pass


if __name__ == '__main__':
    p1 = multiprocessing.Process(target=get_pic)
    p2 = multiprocessing.Process(target=get_gdp_data)

    p1.start()
    p2.start()