当前位置:   article > 正文

Python爬虫入门与进阶

Python爬虫入门与进阶

目录


本文主要是记录了我学爬虫的过程,不喜勿喷~

大家可以用此文来作为一个引导,文中的代码直接复制去python的IDE(比如pycharm或者spider)中就可以运行(需要先安装相应的python库)。小机灵鬼们要仔细学下去的话,文中会有一些链接,当然也可以自行百度/Google,或者买一本书来慢慢看

有一些是我在其他教程里面踩过的坑,比如用老方法(直接用cookie)已经不能模拟登录知乎了QAQ

文中有些链接可能需要翻墙哦

一、学习搭建网站

要用爬虫从网站上抓取信息,要先知道网站的构成和搭建方法

网页构成:
HTML - 定义网页的结构
css - 定义外观
js - 实现各种实时、动态、交互的页面功能

我们可以在pycharm中新建html和css文件,然后搭建自己的网站。

关于python:推荐使用pycharm + anaconda

参考资料:
Python:https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000
Html 教程:http://www.w3school.com.cn/html/index.asp
Css 教程:http://www.w3school.com.cn/css/index.asp
JS 教程:http://www.w3school.com.cn/b.asp
     或者:https://www.liaoxuefeng.com/wiki/001434446689867b27157e896e74d51a89c25cc8b43bdb3000
不一定要都看完才往下学,可以只看前面一点点,需要的时候再查阅(是个正常人都不会有兴趣全部看完的)

二、requests库入门

中文官方文档:http://cn.python-requests.org/zh_CN/latest/

当然还有英文的:http://www.python-requests.org/en/master/

requests快速上手:http://docs.python-requests.org/zh_CN/latest/user/quickstart.html

1、安装(在python中)

pip install requests
  • 1

2、主要方法

方法 用途
requests.get(url, params, **kwargs) 获取HTML网页的主要方法。其中params作为url中的额外参数,用于生成更具体的链接;**kwargs为访问控制参数
requests.head() 获取网页头信息
requests.post() 在网页原有基础上提交新内容
requests.put() 覆盖原有内容
requests.patch() 修改局部内容
requests.delete() 删除各种内容

返回response对象

3、对象的属性

r = requests.xxx(...)
  • 1
属性 内容
r.status_code HTTP请求的返回状态,200代表访问成功,404代表失败
r.text HTTP响应内容的字符串形式
r.encoding 从HTTP head标签中获取的响应内容的编码方式
r.apparent.encoding 从具体响应内容分析出的编码方式
r.content HTTP响应内容的二进制形式
r.cookies
r.headers

输出r.text前,最好先运行语句:
r.encoding = r.apparent.encoding
以避免出现乱码

4、requests库主要功能

基本请求(六种)
文件上传
Cookies登录,回话维持
代理设置
身份认证

三、requests库进阶

1、requests异常

异常 说明
requests.ConnectionError 网络连接错误异常,如DNS查询失败,拒绝连接等
requests.HTTPError HTTP错误异常,即状态码不等于200时
requests.Timeout 请求URL超时
requests.TooManyRedirects 重定向次数太多
requests.ConnectTimeout 连接远程服务器超时异常
requests.URLRequired 缺少URL

2、try-except方法(python)

用于处理程序正常执行过程中出现的一些异常情况,如语法错误、数据除零错误。

一般用来作为爬虫的代码框架,例子:

import requests


# 判断状态码异常
def getHTML(url):
    try:
        r = requests.get(url, timeout=30)
        r.raise_for_status()  # 状态码不等于200时返回1,并跳转到except
        r.encoding = r.apparent_encoding   # 使输出的r.text中不会出现乱码
        return r.text
    except:
        return "产生状态码异常"


url1 = 'http://www.baidu.com'
url2 = 'www.baidu.com'
print(getHTML(url1))
print(getHTML(url2))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

3、高级用法

文件上传

import requests

# 上传一个文件,首先自行创建一个test.txt
file = {'file': open('test.txt', 'rb')}
r = requests.post("https://httpbin.org/post", files=file)  # 该网站是一个适合学习爬虫的测试网站
print(r.text)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

获取cookies

import requests


r = requests.get('http://www.baidu.com')
print(r.cookies)
print('\n')
print(type(r.cookies))
print('\n')
for key, value in r.cookies.items():  #items()方法将其转化为元组组成的列表
    print(key, value)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

会话维持

import requests


# 利用session,请求测试网址https://httpbin.org/cookies/set/number/123,
# 同时设置了一个cookie,名称为number,内容为123
s = requests.session()
s.get('https://httpbin.org/cookies/set/number/123')

r = s.get('https://httpbin.org/cookies')
print(r.text)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

网络图片的下载与保存

打开百度图片,任选一张,右键,在新页面打开,复制图片URL

import requests


url = 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1542903064518&di=49abdd9985efa1e5e7795590c' \
      '34781ce&imgtype=0&src=http%3A%2F%2Fpic3.zhimg.com%2Fv2-3afcf01edb3403f00efd5e4dafa2815b_1200x500.jpg'
r = requests.get(url)
print(r.text[:1000])  # 输出很乱的东西,实际上是像素点变成了str
print(r.content[:1000])  # 输出16进制内容,代表像素点。结果前的b代表这是bytes类型的数据

with open('picture.png', 'wb') as f:
    f.write(r.content)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

用requests来模拟登录:

有兴趣的小机灵鬼可以百度一下新版知乎的模拟登录方法,旧版的单纯用cookie来模拟登录知乎的方法已经无效了。这里就不作展示了emmm我懒

4、练习 - 爬取 百度搜索 页面

使用get()方法中的params参数,获取百度对于某个关键词的搜索页面的源码。同时解决params中的中文编码问题。

import requests


url = 'http://www.baidu.com/s'
keyword = {'wd': '爬虫'.encode('gbk')}
try:
    r = requests.get(url, params=keyword)
    r.raise_for_status()
    r.encoding = r.apparent_encoding
    print(r.text)
except:
    print('获取源码失败')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

可以在浏览器中打开百度,搜索 爬虫,然后对比代码输出的结果。

四、Robots协议

1、爬虫规模

小规模网页爬虫:用requests方法获取网页
中规模网站爬虫:运用scrapy
大规模全网爬虫:多用于搜索引擎,要自己开发,没有第三方库。这就超出我的知识范围了

2、爬虫带来的问题

影响Web服务器性能
隐私泄露

3、爬虫反制的措施

来源审判:判断User-Agent进行限制
发布公告:Robots协议(Robots Exclusion Protocol),告知网络爬虫哪些页面可以抓取,哪些不可以

4、练习 - 爬取亚马逊

伪装成浏览器,爬取亚马逊网页

import requests


url = 'https://www.amazon.cn/dp/B07746N2J9'
header = {'user-agent': 'Mozilla/5.0'}  # 用于伪装成浏览器
try:
    r = requests.get(url, headers=header)
    r.raise_for_status()
    r.encoding = r.apparent_encoding
    print(r.text[:1000])
except:
    print('获取网页失败')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

五、正则表达式

1、简介

正则表达式是一种特殊的字符串模式,用于匹配一组字符串,就好比用模具做产品,而正则表达式就是这个模具,定义一种规则去匹配符合规则的字符串。
参考资料:
https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/00143193331387014ccd1040c814dee8b2164bb4f064cff000

http://www.runoob.com/regexp/regexp-tutorial.html

在线正则表达式测试:http://tool.oschina.net/regex# 在第一个框框中输入要测试的文本,然后在第二个框框输入正则表达式,或者点击右边的一列选项(接着就会出现写好的响应的表达式)

2、re库

如果你的python环境中没有re库,请自行安装。
下面来看看常用的函数。

(1)re.match()

该方法尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回None;如果成功,就返回一个SRE_Match对象。

result = re.match(pattern, string, flags=0)  # patter是正则表达式,string是要匹配的字符串
  • 1

result.group()返回匹配的字符串,result.span()返回的是匹配到的字符串在原字符串中的位置范围。例子:
在这里插入图片描述

(2)re.search()

它在匹配时会扫描整个字符串,然后返回第一个成功匹配的结果。

(3)re.findall()

扫描整个字符串,然后返回所有成功匹配的结果。

(4)re.sub()

用于删掉字符串中的特定内容。

(5)re.compile()

将正则字符串编译成正则表达式对象。

3、爬取猫眼电影网 - 榜单 - top100电影信息

下面来看一下比较凶残的例子:
使用正则表达式,爬取猫眼电影-榜单-最受期待榜中的所有电影(http://maoyan.com/board/6?offset=0 )的信息,并输出到txt文件:

import requests
# 下面这些python库请自行安装
import re
import json
import time


# 爬取单一网页
def get_one_page(url):
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) '  # 伪装成浏览器
                      'Chrome/63.0.3239.132 Safari/537.36'
    }
    r = requests.get(url, headers=headers)
    if r.status_code == 200:
        return r.text
    return None


# 提取单一网页的关键信息
def parse_one_page(html):
    # 使用正则表达式提取关键内容
    pattern = re.compile('<dd.*?board-index.*?">(\d+)</i.*?data-src="(.*?)".*?<p class="name"><a.*?>(.*?)</a>.*'
                       '?<p class="star">(.*?)</p.*?class="releasetime">(.*?)</p.*?</dd>', re.S)  # 第二个参数为re.S,作用是使得 . 可以匹配换行符
    items = re.findall(pattern, html)
    result = []
    for item in items:
        result.append({
            '排名': item[0],
            '海报': item[1],
            '电影名称': item[2],
            '主演': item[3].strip()[3:] if len(item[3]) > 3 else '',
            '上映时间': item[4].strip()[5:] if len(item[4]) > 5 else ''
        })
    return result


# 写进txt文件
def write_to_file(content):
    with open('result2.txt', 'a', encoding='utf-8') as f:
        # print(type(json.dumps(content)))
        # 先将content转换为字符串格式,然后再写入文件
        f.write(json.dumps(content, ensure_ascii=False) + '\n')


def main(offset):
    url = 'http://maoyan.com/board/6?offset=' + str(offset)
    html = get_one_page(url)
    for item in parse_one_page(html):
        print(item)
        write_to_file(item)


if __name__ == '__main__':
    # 因为每一页只有10部电影,所以需要循环提取
    for i in range(10):
        main(offset=i * 5)
        # 访问完每页后停一小会,对应反爬虫机制
        time.sleep(1)
  
# 前五条输出:
# {'排名': '1', '海报': 'http://p1.meituan.net/movie/c7453592d38b7aff6a774a52732792cd3778866.jpg@160w_220h_1e_1c', '电影名称': '人间·喜剧', '主演': '艾伦,王智,鲁诺', '上映时间': '2018-12-07'}
# {'排名': '2', '海报': 'http://p0.meituan.net/movie/c304c687e287c7c2f9e22cf78257872d277201.jpg@160w_220h_1e_1c', '电影名称': '龙猫', '主演': '秦岚,糸井重里,岛本须美', '上映时间': '2018-12-14'}
# {'排名': '3', '海报': 'http://p0.meituan.net/movie/e5f0a55327d5be1caa9f110abcca23865841112.jpg@160w_220h_1e_1c', '电影名称': '飞驰人生', '主演': '沈腾,黄景瑜,尹正', '上映时间': '2019-02-05'}
# {'排名': '4', '海报': 'http://p1.meituan.net/movie/9cd36871e75c756f3ad175afa6452cf2177292.jpg@160w_220h_1e_1c', '电影名称': '疯狂的外星人', '主演': '黄渤,沈腾,马修·莫里森', '上映时间': '2019-02-05'}
# {'排名': '5', '海报': 'http://p1.meituan.net/movie/c57e3e283679ab6efab23b16a2d20364838623.jpg@160w_220h_1e_1c', '电影名称': '情圣2', '主演': '吴秀波,白百何,肖央', '上映时间': '2019-02-05'}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67

六、网页内容解析

前面介绍了使用正则表达式来提取内容的方法,但是一大堆正则表达式,看着就想杀人

于是,可爱的程序猿们开发出了各种解析工具。鼓掌.jpg

1、使用Beautiful Soup

Beautiful Soup是Python的一个HTML或XML的解析库,可以用来方便地提取我们想要的网页内容。

(1)解析器

Beautiful Soup在解析时实际上依赖解析器,它支持一下四种解析器:

解析器 使用方法 advantage 坑爹的地方
Python标准库 BeautifulSoup(markup, “html.parser”) Python内置 Python 2.7.3 or 3.2.2 前 的版本中文档容错能力差
lxml HTML解析器 BeautifulSoup(markup, “lxml”) 速度快 需要安装lxml
lxml XML解析器 BeautifulSoup(markup, “xml”) 速度快ÿ
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/848637
推荐阅读
相关标签
  

闽ICP备14008679号