爬虫简介与requests模块

本文介绍了网络爬虫的基本概念及其价值,并详细讲解了Python中的requests模块,包括基本用法、GET和POST请求、响应对象、代理IP等。通过爬取豆瓣Top250书籍和GitHub首页的例子,帮助读者掌握爬虫实战技巧。
摘要由CSDN通过智能技术生成

爬虫简介

概述

近年来,随着网络应用的逐渐扩展和深入,如何高效的获取网上数据成为了无数公司和个人的追求,在大数据时代,谁掌握了更多的数据,谁就可以获得更高的利益,而网络爬虫是其中最为常用的一种从网上爬取数据的手段。
网络爬虫,即Web Spider,是一个很形象的名字。如果把互联网比喻成一个蜘蛛网,那么Spider就是在网上爬来爬去的蜘蛛。网络蜘蛛是通过网页的链接地址来寻找网页的。从网站某一个页面(通常是首页)开始,读取网页的内容,找到在网页中的其它链接地址,然后通过这些链接地址寻找下一个网页,这样一直循环下去,直到把这个网站所有的网页都抓取完为止。
在这里插入图片描述

爬虫的价值

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

robot.txt协议

如果自己的门户网站中的指定页面中的数据不想让爬虫程序爬取到的话,那么则可以通过编写一个robots.txt的协议文件来约束爬虫程序的数据爬取。robots协议的编写格式可以观察淘宝网的robots(访问www.taobao.com/robots.txt即可)。但是需要注意的是,该协议只是相当于口头的协议,并没有使用相关技术进行强制管制,所以该协议是防君子不防小人。但是我们在学习爬虫阶段编写的爬虫程序可以先忽略robots协议。

爬虫的基本流程

在这里插入图片描述

requests模块

Requests是用python语言基于urllib编写的,采用的是Apache2 Licensed开源协议的HTTP库,Requests它会比urllib更加方便,可以节约我们大量的工作。一句话,requests是python实现的最简单易用的HTTP库,建议爬虫使用requests库。默认安装好python之后,是没有安装requests模块的,需要单独通过pip安装
pip install requests

基本用法

requests模块支持的请求

import requests
requests.get("http://httpbin.org/get")
requests.post("http://httpbin.org/post")
requests.put("http://httpbin.org/put")
requests.delete("http://httpbin.org/delete")
requests.head("http://httpbin.org/get")
requests.options("http://httpbin.org/get") 

get请求

在说get请求之前,先要弄明白服务器是如何区别我们发出的请求到底是浏览器发出的还是代码发出的?
其中一个重要的区别就是在请求头中有UA标识。

User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36

在这里插入图片描述
1.基本请求

import requests
response=requests.get('https://www.jd.com/',)
 
with open("jd.html","wb") as f:
    f.write(response.content)

2.含参数请求

import requests
response=requests.get('https://s.taobao.com/search?q=手机')
response=requests.get('https://s.taobao.com/search',params={"q":"美女"})

3.含请求头请求

import requests
response=requests.get('https://dig.chouti.com/',
             headers={
                   'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.75 Safari/537.36',
                         }
                      )

4.含cookies请求

import uuid
import requests

url = 'http://httpbin.org/cookies'
cookies = dict(sbid=str(uuid.uuid4()))

res = requests.get(url, cookies=cookies)
print(res.text)

post请求

1 data参数
requests.post()用法与requests.get()完全一致,特殊的是requests.post()多了一个data参数,用来存放请求体数据

response=requests.post("http://httpbin.org/post",params={"a":"10"}, data={"name":"yuan"})

2 发送json数据

import requests
#没有指定请求头,#默认的请求头:application/x-www-form-urlencoed
res1=requests.post(url='http://httpbin.org/post', data={'name':'yuan'}) 
print(res1.json())
 
#默认的请求头:application/json
res2=requests.post(url='http://httpbin.org/post',json={'age':"22",}) 
print(res2.json())

response对象

1.常见属性

import requests
respone=requests.get('https://sh.lianjia.com/ershoufang/')
# respone属性
print(respone.text)
print(respone.content)
print(respone.status_code)
print(respone.headers)
print(respone.cookies)
print(respone.cookies.get_dict())
print(respone.cookies.items())
print(respone.url)
print(respone.history)
print(respone.encoding)

2.编码问题

import requests
response=requests.get('http://www.autohome.com/news')
#response.encoding='gbk' 
#汽车之家网站返回的页面内容为gb2312编码的,
# 而requests的默认编码为ISO-8859-1,如果不设置成gbk则中文乱码
with open("res.html","w") as f:
    f.write(response.text)

3.下载二进制文件

import requests
response=requests.get('http://bangimg1.dahe.cn/forum/201612/10/200447p36yk96im76vatyk.jpg')
with open("res.png","wb") as f:
    # f.write(response.content) 
    # 比如下载视频时,如果视频100G,用response.content然后一下子写到文件中是不合理的
    for line in response.iter_content():
        f.write(line)

4.解析json数据

import requests
import json
 
response=requests.get('http://httpbin.org/get')
res1=json.loads(response.text) #太麻烦
res2=response.json() #直接获取json数据
print(res1==res2)

5 history
响应对象的 history 方法来追踪重定向

>>> r = requests.get('http://github.com')
>>> r.url
'https://github.com/'
>>> r.status_code
200
>>> r.history
[<Response [301]>]

另外,还可以通过 allow_redirects 参数禁用重定向处理:

>>> r = requests.get('http://github.com', allow_redirects=False)
>>> r.status_code
301
>>> r.history
[]  

代理ip

一些网站会有相应的反爬虫措施,例如很多网站会检测某一段时间某个IP的访问次数,如果访问频率太快以至于看起来不像正常访客,它可能就会会禁止这个IP的访问。所以我们需要设置一些代理服务器,每隔一段时间换一个代理,就算IP被禁止,依然可以换个IP继续爬取。

res=requests.get('http://httpbin.org/ip', proxies={'http':'110.83.40.27:9999'}).json()
print(res)

爬虫小案例

爬取豆瓣top250
import requests
import re
import json

# 获取爬取的页面
def get_pages(url,headers):
    response = requests.get(url,headers=headers)
    return response

# 解析数据
def parse(response):
    reg = re.compile('<div class="item">.*?<a href="(?P<url>.*?)">.*?<span class="title">(?P<title>.*?)</span>.*?<span class="rating_num".*?>(?P<rating_num>.*?)</span>.*?<span>(?P<commet_num>.*?)人评价</span>',re.S)
    data_iter = reg.finditer(response.text)
    # print(data_iter)
    # for i in data_iter:
    #     print(i.group('url'))
    #     print(i.group('title'))
    return data_iter

# 存储数据
def store(data_iter):
    movie_info = {}
    for i in data_iter:
        url = i.group('url')
        title = i.group('title')
        rating_num = i.group('rating_num')
        commet_num = i.group('commet_num')
        movie_info["url"] = url
        movie_info["title"] = title
        movie_info["rating_num"] = rating_num
        movie_info["commet_num"] = commet_num

        with open("douban.txt","a",encoding="utf-8") as f:
            f.write(json.dumps(movie_info,ensure_ascii=False)+"\n")


def spider_movie(url,headers):
    response = get_pages(url,headers)
    data_iter = parse(response)
    store(data_iter)

def main():
    count = 0
    headers = {
        "User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1"
    }
    for i in range(10):
        url = "https://movie.douban.com/top250?start=%s&filter=" % count
        count+=25
        spider_movie(url,headers)

if __name__ == "__main__":
    main()

爬取github的home页(重点是反爬)

import requests,re

# 请求获取token,以便通过post请求的校验
res_get = requests.get("https://github.com/login")
cookies = res_get.cookies.get_dict()
token =re.findall('<input type="hidden" name="authenticity_token" value="(.*?)".*?>',res_get.text,re.S)


headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36",
}
# 构建post请求数据
data = {
    "commit": "Sign in",
    "authenticity_token": token[0],
    "ga_id": "145266425.1563942942",
    "login": "1240557686@qq.com",
    "password": "12333315862",
    "webauthn-support": "supported",
    "webauthn-iuvpaa-support": "unsupported",
    "return_to": "/join?ref_cta=Sign+up&ref_loc=header+logged+out&ref_page=%2Fenterprise&source=header",
    "required_field_e104":"",
    "timestamp": "1601457021037",
    "timestamp_secret": "c7834b62a1487e6d6ee4cbbac9e001d299ed27e2d6a98c247fb5050bd0ed4711"
}

res = requests.post("https://github.com/session",data=data,cookies=cookies)

with open("github.html","wb") as f:
    f.write(res.content)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值