python之爬虫入门

  • **

一、爬虫的准备工作

**
1) 你想爬取什么数据?
2) 找到数据对应的网页
3) 分析网页结构找到数据所在的标签位置
4) 找到你想爬取的页面,按F12,按小箭头找到你要爬取的内容
5) 模拟HTTP请求,向服务器发出这个请求,获取到服务器返回给我们HTML
用正则表达式,bs4,xpath提取我们要的数据

二、爬虫神器requests模块

****注:Requests是同步模块,要使用异步时,用异步模块,异步模块详解后续讲解

1. Requests模块的安装

第一种方法安装:
1、找到pip3.exe所在的文件夹,复制路径
2、标题栏输入CMD确定进去DOS,
3、输入 pip3 install requests 回车,

第二种方法安装:
在pycharm中底下有Terminal,进入后直接输入pip3 install requests就可以安装

2. Requests方法
requests.request() 构造一个请求,支撑一下各方法的基础方法
requests.get() 获取HTML网页的主要方法,对应HTTP的GET** [常用]**
requests.head() 获取HTML网页头的信息方法,对应HTTP的HEAD
requests.post() 向HTML网页提交POST请求方法,对应HTTP的POST** [常用]**
requests.put() 向HTML网页提交PUT请求的方法,对应HTTP的RUT
requests.patch() 向HTML网页提交局部修改请求,对应于HTTP的PATCH
requests.delete() 向HTML页面提交删除请求,对应HTTP的DELETE

3. Requests属性 在这里插入图片描述
例:

import requests
url = 'https://www.baidu.com'
response  = requests.get(url)  
print(response)                      # <Response [200]>
print(response .status_code)        # 查看状态,200为正常,404为错误
print(type(response ) )            # 查看它的类  <class 'requests.models.Response'>  这是response类
print(response .headers)          # 获得头部信息
print(response.request.headers)  # 查看UA伪装
print(response.url)             # 查看请求的网址
print(response.request.url)    # 查看请求的网址

三、UA伪装[必备]

使用get/post发请求不是浏览器,是爬虫程序,网站为了服务器压力问题,它们不欢迎非人类访问。
所以我们要把程序伪装成浏览器去访问网站。简称UA伪装。
解析网站内容必须要用UA,若只是获取2进制的数据[直接下载 文件,已到最后一步],则可以不需要UA。
如果只用一个UA很容易被反爬虫识别,我可以做很多个UA头,随便百度找,有很多,然后每次访问的时候可以随机选一个。

import random
user_agent = [
    "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50",
    "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50",
    "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0",
    "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729; InfoPath.3; rv:11.0) like Gecko",
    "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)"]
    
 headers = {'User-Agent': random.choice(user_agent)}  # 随机选一个 

四、数据解析

**1. HTML格式
在这里插入图片描述
HTML(Hyper Text Markup Language)超文本标记语言,是我们编写网页的最基本也是最核心的一种语言.其语法规则就是用不同的标签对网页上的内容进行标记,从而使网页显示出不同的展示效果.

 <h1>
         我爱你
</h1>

上述代码的含义是在页面中显示"我爱你"三个字,但是我爱你三个字被h1>和/h1标记了、白话就是被括起来了.被h1这个标签括起来了、这个时候、浏览器在展示的时候就会让我爱你变粗变大.俗称标题,所以HTML的语法就是用类似这样的标签对页面内容进行标记.不同的标签表现出来的效果也是不一样的.
1) h1: 一级标题
2) h2: 二级标题
3) p:段落
4) font:字体(被废弃了,但能用)
5)body:主体

2. 正则表达式数据解析案例[案例引用bilibili孙兴华老师的案例]

import requests
import re
import os
# 创建一个文件夹,保存所有图片
if not os.path.exists('./海报'):
    os.mkdir('./海报')    
url = 'http://www.jkl.com.cn/cn/phoLis.aspx?id=697'
for i in range(1,5):
    data = {'__EVENTARGUMENT':'i'}
    UA伪装 = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.92 Safari/537.36'}
    # 使用通过爬虫对url对应的一整张页面进行爬取
    响应数据 = requests.get(url=url,params=data,headers=UA伪装).text
    # 使用聚焦爬虫将页面中所有的图片进行解析/提取
    # (?=exp):零宽度正回顾后发断言,它断言自身出现的位置的前面能匹配表达式exp
    # (?<=exp): 零宽度正回顾后发断言,它断言自身出现的位置的前面能匹配表达式exp
    正则 = '(?<=\<img src\=").+?(?=" width\="165" height\="117")'    
    图片地址列表 = re.findall(正则,响应数据)
    for ulr2 in 图片地址列表:
        # 拼接出一个完整的图片地址
        ulr2 ='http://www.jkl.com.cn'+ulr2
        # 请求到了图片的二进制数据
        图片数据 = requests.get(url=ulr2,params=data,headers=UA伪装).content
        # 生成图片名称
        图片名字 = str(i)+ulr2.split('/')[-1]    
        # 图片存储的路径
        图片路径 = './海报/'+图片名字
        # 持久化存储
        with open(图片路径,'wb') as 变量名:
            变量名.write(图片数据)
            print(图片名字,'下载成功!!!')

3. bs4数据解析
引用:

— By: 牧小熊

华中农业大学研究生,Datawhale成员, Datawhale优秀原创作者

知乎:https://www.zhihu.com/people/muxiaoxiong
—————————————————————————————————————————————

安装方法:

pip install bs4

conda install bs4


我们来解析豆瓣读书 Top250 

它的网址是:https://book.douban.com/top250

项目难度:⭐⭐

```python
import io
import sys
import requests
from bs4 import BeautifulSoup
###运行出现乱码时可以修改编码方式
#sys.stdout = io.TextIOWrapper(sys.stdout.buffer,encoding='gb18030')
###
headers = {
  'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36'
}
res = requests.get('https://book.douban.com/top250', headers=headers)
soup = BeautifulSoup(res.text, 'lxml')
print(soup)

python 打印信息时会有限制 我们将打印的编码改成gb18030

headers表示我们的请求网页的头,对于没有headers的请求可能会被服务器判定为爬虫而拒绝提供服务

通过 from bs4 import BeautifulSoup 语句导入 BeautifulSoup

然后使用 BeautifulSoup(res.text, lxmlr’) 语句将网页源代码的字符串形式解析成了 BeautifulSoup 对象

解析成了 BeautifulSoup 对象可以较为方便的提取我们需要的信息

那么如何提取信息呢?

BeautifulSoup 为我们提供了一些方法

find()方法find_all()方法

  • find() 返回符合条件的首个数据
  • find_all() 返回符合条件的所有**数据
import io
import sys
import requests
from bs4 import BeautifulSoup
#如果出现了乱码报错,可以修改编码形式
#sys.stdout = io.TextIOWrapper(sys.stdout.buffer,encoding='gb18030')
#
headers = {
  'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36'
}
res = requests.get('https://book.douban.com/top250', headers=headers)
soup = BeautifulSoup(res.text, 'lxml')
print(soup.find('a'))
#<a class="nav-login" href="https://accounts.douban.com/passport/login?source=book" rel="nofollow">登录/注册</a>
print(soup.find_all('a'))
#返回一个列表 包含了所有的<a>标签

除了传入 HTML 标签名称外,BeautifulSoup 还支持熟悉的定位

# 定位div开头 同时id为'doubanapp-tip的标签
soup.find('div', id='doubanapp-tip')
# 定位a抬头 同时class为rating_nums的标签
soup.find_all('span', class_='rating_nums')
#class是python中定义类的关键字,因此用class_表示HTML中的class

4. xpath数据解析
xpath 是在XML文档中搜索内容的一门语言。
html是XML的一个子集;
一、解析原理
1、实例化一个etree的对象,且需要将被解析的页面源码数据加载到该对象中。
2、调用etree对象中的xpath方法结合着xpath表达式实现标签的定位和内容的捕获。

二、导入类
from lxml import etree

三、如何实例化一个etree对象
1、将本地的html文档中的源码数据加载到etree对象中
etree.parse(文件路径)
2、可以将从互联网上获取源码数据加载到该对象中
etree.HTML(响应数据)

四、xpath表达式
/:表示的是从根节点开始定位,表示的是一个层级
//:表示是多个层级,可以表示从任意位置开始定位
属性定位://div[@class=‘song’] tag[@attrName=“attrValue”]
索引定准://div[@class=‘song’]/p[3] 索引从1开始的
取文本:

/text():获取的是标签中真系的文本内容
//text():标签中非真系的文本内容(所有的文本内容)
取属性:

/@arrtName 例如 ==>img/src
./表示当前的下一级

五、简单的入门爬取案例[案例来自于bilbili孙兴华老师的案例]

import requests                      # 导入库
import pandas as pd                 # 导入pd库
from lxml import etree             # 导入解析库
path = r''  # 存入内容的地址
url = 'http://www.jkl.com.cn/cn/shop.aspx'      # 获取的店铺的主网页
UA = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.92 Safari/537.36'}           # UA伪装
# 1. 先拿到每一个城区
response = requests.get(url=url,headers=UA).text   # 请求
tree = etree.HTML(response)   # 解析网址
city = tree.xpath('//div[@class="infoLis"]//@href')   # 获取解析网址下的子网址
# print(city)    # 输出为:'shopLis.aspx?id=862'  ……
# 2.对每个城区进行解析
forin city:
    url2 = 'http://www.jkl.com.cn/cn/' +# 拼接网址[从该网址下访问具体的内容]
    # print(url2)   # 输出为: https://www.jkl.com.cn/cn/shopLis.aspx?id=862  …… 
    response1 = requests.post(url=url2, headers=UA伪装).text
    tree1 = etree.HTML(response1)
    店铺名称 = tree1.xpath('//span[@class="con01"]/text()')  # 因网站上就有回车和换行,所以获取到的也带
    #print(店铺名称)  # 输出为:['\r\n               京客隆永安路店', '\r\n                 京客隆里仁街店']
    详细地址 = tree1.xpath('//span[@class="con02"]/text()')
    电话号码 = tree1.xpath('//span[@class="con03"]/text()')
    营业时间 = tree1.xpath('//span[@class="con04"]/text()')
    list1 = []   # 创建一个空列表,放入去除换行的内容
    for 店名 in 店铺名称:  # 通过遍历去除里面的回车和换行
        #print(店名)   # 查看一下
        newdata1 =.strip()  # 去除回车和换行
        list1.append(newdata1)  # 把去除后的内容增加到列表
    data1 = pd.DataFrame({'店名': list1, '地址': 详细地址, '电话': 电话号码, '时间': 营业时间})
    data1.to_csv(path,index=False,header=0,mode='a',encoding='ANSI')   # encoding有中文时ANSI
    # 当城市属于朝阳区的时候,信息是多页的
    if url2 == 'http://www.jkl.com.cn/cn/shopLis.aspx?id=865':
        for i in range(2, 4):
            data = {'__EVENTARGUMENT': i,
                    '__EVENTTARGET': 'AspNetPager1'
                    }
            response2 = requests.post(url=url2, data=data, =UA).text  # post无法获取,使用get获取的翻页
		#response2 = requests.get(url=url2, params=data, headers=UA).text  # 跟着视频post无法获取,只能用get
            tree2 = etree.HTML(response2)
            店铺名称 = tree2.xpath('//span[@class="con01"]/text()')
            详细地址 = tree2.xpath('//span[@class="con02"]/text()')
            电话号码 = tree2.xpath('//span[@class="con03"]/text()')
            营业时间 = tree2.xpath('//span[@class="con04"]/text()')
            list2 = []
            forin 店铺名称:
                newdata2 =.strip()
                list2.append(newdata2)
            # print(详细地址)
            data2 = pd.DataFrame({'店名':list2, '地址': 详细地址, '电话': 电话号码, '时间': 营业时间})
            data2.to_csv(path, index=False, header=0, mode='a', encoding='ANSI')
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值