【python】【爬虫】妖精的爬虫学习之路——基础入门

一.基本原理

爬虫即网络爬虫,英文是Web Spider。翻译过来就是网络上爬行的蜘蛛,如果把互联网看作一张大网,那么爬虫就是在大网上爬来爬去的蜘蛛,碰到想要的食物,就把他抓取出来。

我们在浏览器中输入一个网址,敲击回车,看到网站的页面信息。这就是浏览器请求了网站的服务器,获取到网络资源。那么,爬虫也相当于模拟浏览器发送请求,获得到HTML代码。HTML代码里通常包含了标签和文字信息,我们就从中提取到我们想要的信息。

通常爬虫是从某个网站的某个页面开始,爬取这个页面的内容,找到网页中的其他链接地址,然后从这个地址爬到下一个页面,这样一直不停的爬下去,进去批量的抓取信息。那么,我们可以看出网络爬虫就是一个不停爬取网页抓取信息的程序。

爬虫的工作流程

1.发起请求:
通过HTTP库向目标站点发起请求,即发送一个Request,请求可以包含额外的headers等信息,然后等待服务器响应。这个请求的过程就像我们打开浏览器,在浏览器地址栏输入网址:www.baidu.com,然后点击回车。这个过程其实就相当于浏览器作为一个浏览的客户端,向服务器端发送了 一次请求。

2.获取响应内容:
如果服务器能正常响应,我们会得到一个Response,Response的内容便是所要获取的内容,类型可能有HTML、Json字符串,二进制数据(图片,视频等)等类型。这个过程就是服务器接收客户端的请求,进过解析发送给浏览器的网页HTML文件。

3.解析内容:
得到的内容可能是HTML,可以使用正则表达式,网页解析库进行解析。也可能是Json,可以直接转为Json对象解析。可能是二进制数据,可以做保存或者进一步处理。这一步相当于浏览器把服务器端的文件获取到本地,再进行解释并且展现出来。

4.保存数据:
保存的方式可以是把数据存为文本,也可以把数据保存到数据库,或者保存为特定的jpg,mp4 等格式的文件。这就相当于我们在浏览网页时,下载了网页上的图片或者视频。

二.实战干货

1.request 包

request基于urllib3,整合了urllib系列的常用操作,非常方便
代码示例:

import requests
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36'}
response = requests.get('http://www.baidu.com', headers=headers)
print(response.text)

释义:

  • 添加headers是因为有些网页会禁止爬虫的访问,检查是否是浏览器访问。这个时候我们就要给爬虫加一个headers,加一个浏览器的user-agent信息。(user-agent可以在任意浏览器打开 ‘developer tools’,中文版似乎是叫‘审查元素’?,然后点任意页面,在‘network’选项,request header下有 user-agent字段)
  • response可以得到的信息:response.status_code # 状态码 response.text # 网页源码 response.headers # 头部信息 response.cookies # Cookie response.url # 请求的url response.history # 访问的历史记录

PS:可以使用POST方法传参(在能传参的页面)

2.使用request下载图片

import requests
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36'}
response = requests.get('ttps://www.baidu.com/img/baidu_jgylogo3.gif', headers=headers)
with open('logo.jpg', 'wb') as f:
    f.write(response.content)

3.使用request.post上传图片

import requests
files = {'file' : open('logo.jpg','rb')}
resp = requests.post('http://httpbin.org/post', files=files)
print(resp.text)

把刚刚下载的logo.jpg传到 http://httpbin.org 虽然我并没发现这样子传上去会对httpbin这个网页造成什么影响,但是回显的response还是很清楚的可以看到图片的字节流的。个人学艺不精的感觉,post方法应该主要是用于提交表单/登陆等操作。

4.使用BeautifulSoup解析网页

beautifulSoup可以提供很多便捷的方法,可以直接搜索网页中我们需要的内容。下面是BS的基本用法:

from bs4 import BeautifulSoup
import lxml
import requests

html_doc = requests.get('https://book.douban.com/top250?start=0')
soup = BeautifulSoup(html_doc.text,'lxml')

div = soup.find_all("div", class_ = 'pl2')
for item in div:
    print(item.find('a')['title'])

打印出豆瓣排行页面的全部书名

把豆瓣书名+作者+评分等全部输出的完整代码:
自己练手的辣鸡版本~

from bs4 import BeautifulSoup
import lxml
import requests

html_doc = requests.get('https://book.douban.com/top250?start=0')
soup = BeautifulSoup(html_doc.text,'lxml')

div = soup.find_all("div", class_ = 'pl2')
names = [a.find('a')['title'] for a in div]
s = soup.find_all('span', class_ = 'rating_nums')
scores = [sco.get_text() for sco in s]
dis = soup.find_all('span', class_ = 'inq')
quotes = [d.get_text() for d in dis]

with open('小测试.txt', 'w', encoding='utf-8') as f:
    for name, score, quote in zip(names,scores, quotes):
        name = '书名:' + name + '\n'
        score = '评分:' + score +'\n'
        quote = '箴言:' +quote + '\n'
        data = name + score + quote
        f.writelines(data + '=======================' + '\n')

生成的txt效果:
在这里插入图片描述

大神的教学版本:

# -*- coding:utf-8 -*-
#  author: yukun
import requests
from bs4 import BeautifulSoup
 
 
# 发出请求获得HTML源码的函数
def get_html(url):
    # 伪装成浏览器访问
    headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36'}
    resp = requests.get(url, headers=headers).text
 
    return resp
 
# 解析页面,获得数据信息
def html_parse():
    # 调用函数,for循环迭代出所有页面
    for url in all_page():
        # BeautifulSoup的解析
        soup = BeautifulSoup(get_html(url), 'lxml')
        # 书名
        alldiv = soup.find_all('div', class_='pl2')
        names = [a.find('a')['title'] for a in alldiv]
        # 作者
        allp = soup.find_all('p', class_='pl')
        authors = [p.get_text() for p in allp]
        # 评分
        starspan = soup.find_all('span', class_='rating_nums')
        scores = [s.get_text() for s in starspan]
        # 简介
        sumspan = soup.find_all('span', class_='inq')
        sums = [i.get_text() for i in sumspan]
        for name, author, score, sum in zip(names, authors, scores, sums):
            name = '书名:' + str(name) + '\n'
            author = '作者:' + str(author) + '\n'
            score = '评分:' + str(score) + '\n'
            sum = '简介:' + str(sum) + '\n'
            data = name + author + score + sum
            # 保存数据
            f.writelines(data + '=======================' + '\n')
 
# 获得所有页面的函数
def all_page():
    base_url = 'https://book.douban.com/top250?start='
    urllist = []
    # 从0到225,间隔25的数组
    for page in range(0, 250, 25):
        allurl = base_url + str(page)
        urllist.append(allurl)
 
    return  urllist
 
# 文件名
filename = '豆瓣图书Top250.txt'
# 保存文件操作
f = open(filename, 'w', encoding='utf-8')
# 调用函数
html_parse()
f.close()
print('保存成功。')

差异:除了教学版本里使用了比较优雅的编码方式和合适的方法封装之外,我自己只打印了 https://book.douban.com/top250?start= 0的第一页的内容,大神遍历了所有250本书。向大神致敬!(学习链接最下面附上)

PS:豆瓣的TOP250因为页数是固定的,可以写成固定值,如果要爬取的页面数量是不固定的,可以用如下方法获取总的页数:

# so为传入的soup,这里的例子是获取的豆瓣TOP250页数
def get_pages(so):
    pages = so.find('div', class_ = 'paginator')
    page = [p.get_text() for p in pages.find_all('a')]
    return len(page)

参考资料:https://www.jqhtml.com/13275.html

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值