python爬虫requests,原理讲解,轻松理解并实操

        大家好,今天我来给大家分享一下爬虫。对于网页中几百几千页的数据,手动是不可能,而且容易出错,这时候爬虫就站出来了,一个for循环,完成重复的工作。话不多说,直接进入正题。

------思路部分-----(不想听的可以直接滑下去)        

        大部分网站都具备一定的反爬措施,首先我们要了解前端与服务器之间的关系。前端,也就是我们自己电脑的浏览器页面,在浏览器页面右击,点检查,我们可以看到很多代码,这些代码经过浏览器的解析,转换为一定的格式显示在屏幕上。服务器是对方的,你要访问一个网页,首先需要浏览器向对方服务器发送一个请求,请求访问,对方服务器确定了可以让你访问,那么就会返回一个数据包到你电脑上,浏览器解析该包,转换为一定的格式显示在屏幕上。

        那么你访问一个网址,向对方服务器发送请求后,假如对方服务器不同意你的访问,你就得不到数据。生活中很多情况都会使得对方服务器不同意你的访问,比如你没有权限,又或者你是爬虫程序发起的请求,因为爬虫程序执行速度很快,每秒访问几十次,对方服务器会造成压力。有些网站就会拒绝爬虫的访问。

        我们可以通过利用爬虫,伪装成浏览器去向对方发起访问请求,需要注意的是不要过于频繁,后面我会告诉你怎么做不频繁,不着急,一步一步来。千言万语说不清,下面是具体的操作和原理结合,方便理解。

一、页面提取型

        我们以节节草-搜狗百科为例。目标:获取所有图片链接,并下载到本地上。 

图1 浏览器页面

1.  获取网址、headers、cookie和params等参数

        搜索“节节草”进入搜狗百科,如图1界面。然后右击网页,点“检查”,点“网络”,进入到该页面。第4步很重要!!!。浏览器英文的伙伴自己翻译一下哈。

图2

         在“标头”里,网址为“请求URL”,如果不是中文,相信你也能看得出。然后往下滑,找到User-Agent和Cookie。留意一下请求方法,是get还是post。

        这里可以说一下原理,对方服务器和电脑浏览器是以Cookie作为“密码”的,就是说,你现在访问网页,对方服务器与你浏览器之间有一个约定,你规定时间内的的下一次访问要带着这个Cookie去访问,对方服务器就知道是你,不然下次的访问可能会不成功,因为在对方服务器眼里没有这个“人”。超出规定时间后,Cookie便失效,失效便无法访问,需要重新获取Cookie。这就是为什么同样的代码,今天能运行,过几天却报错的原因之一。

        爬虫除了需要url、User-Agent、Cookie,当页面中有多页的时候,需要用到params,页码就存在里面。我的params在“负载”里,有些浏览器会同样放在“标头”下,大概叫“date_form”,我也不是记得很清楚。注意图2的第四步,别不小心点到其他包去找,找不到的。需要你去寻找,找到了下次自然便会。

图3

2.  代码访问

        获取到这几个参数后我们就可以开始写爬虫啦!我们说过,用爬虫伪装成浏览器去访问。由于这里没有翻页,params的理解不太明显。后面爬股票的例子再带大家用一下它。

import requests
web = 'https://baike.sogou.com/v223998.htm?fromTitle=%E8%8A%82%E8%8A%82%E8%8D%89'
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36 Edg/112.0.1722.39',
          'Cookie': 'ssuid=524029849; SUV=001F49727571B9618005EF60C6903; wuid=AAHrKNKSOQAAAAqHQ2VeAAkwA=; SUID=3F605EBE50A00A0000000061B62487; sg_client_ip=120.86.114.181; uname=sg_85db5b10a39bd2e6030faac6e3b0aa; SGINPUT_UPSCREEN=167013632956; cuid=AAG78+VCQwAAAqHSVFAgIANgg=; ABTEST=3|168531092|v17; SNUID=A6A99F092421DD7334D7484249A2FE3; sw_uuid=588057536; IPLOC=CN1200; JSESSIONID=2DBAFF24A2A6A6B65DD9FE450A0B6A; scssuid=778849646'}
params = {'fromTitle': '节节草'}

req = requests.get(url=web,headers=headers,params=params)
print(req.status_code)

         可能你看到这篇文章时cookie已经失效,所以代码还是需要你自己替换哈,把你在你浏览器找到的User-Agent和Cookie替换进去。第6行若请求方式为post那就用post,是get就用get。注意 ''  :  . 等标点符号都需要为英文,中文是不行的。status_code意思是查看状态码,若返回200则表示请求成功,返回400等表示失败,检查代码是否写错了。

图4 请求成功

        请求成功后我们也可以查看网页代码,看看页面的编码有没有问题。如果出现无法显示的文字,那就是编码错了,也可以提前设置编码后再查看网页代码。如下:

图5 编码无误

3.  网页解析并提取链接

        请求成功后便可以对网页进行解析,用Beautifulsoup。把我们获取的网页req.text放入解析库中,html.parser为解析的方法,还有很多,用这个就好了。soup.findAll(name='img')为在解析后的页面中提取标签为<img>的所有行。

        浏览器页面回到“元素”界面(在“网络”同一栏,找一找),发现图片都是以<img>形式存在的,而<img>为标签,用soup.findAll(name='img')提取所有标签为<img>的行。

from bs4 import BeautifulSoup
soup = BeautifulSoup(req.text,'html.parser')
images = soup.findAll(name='img')
for image in images:
    print(image)
    print('-'*70)
图6 元素界面

        很成功能把行提取出来,结果如下:

图7 有3行标签含<img>

 把代码改一下,提取每行中的src,即图片链接。

from bs4 import BeautifulSoup
soup = BeautifulSoup(req.text,'html.parser')
images = soup.findAll(name='img')
d = []
for image in images:
    link = image.get('src')
    if 'http' in link:
        d.append(link)
    else:
        d.append('https:'+link)
for i in d:
    print(i)
图8 获取图片链接

4.  把图片保存到电脑

import time
n = 1
for i in d:
    requ = requests.get(url=i)
    data = requ.content
    road = f"C:/Users/流光、月影/Desktop/{n}.png"
    with open(road,'wb') as fi:
        fi.write(data)
    n += 1
    time.sleep(2)

        这段小白可能无法理解,可以说,新手看不懂,懂的一看就会。

        这里解释一下上面提到的不要过于频繁操作。需要用到time时间库,time.sleep(秒数),程序会等待某秒数后才继续运行下去,这样就能避免对对方服务器造成太大压力。

二、数据包

        这种方法叫简单,但也不是所有网站都符合条件,对获取到的数据进行保存时也是需要对pandas库有一定的基础。条件是查询返回的数据是字典形式,可以直接保存到表格中,省去解析网页的步骤。说不清楚,马上带大家体验一下,我们这次爬股票,以新浪财经为例,网址:行情中心_新浪财经_新浪网

图9 网址页面

         为了体现params的翻页功能,我们选个多页的股票,A股 > 申万一级 > 国防军工 (该图不能放,会违规)

图10 目标页面有4页

        原理上面讲过,我们直接进入实操。

图11 步骤

        刷新后,“网络”页面就多了很多“包”,为了找到数据包,点击Fetch/XHR,可以筛掉图片、图标、js等,点击预览可以对每个包进行查看,发现数据存在于最后一个包里,如下:

图12

        然后在该包下找到网址、headers、cookie和params等参数(在“标头”或“负载”),接着写代码访问网站。

import requests
import pandas as pd

web = 'https://vip.stock.finance.sina.com.cn/quotes_service/api/json_v2.php/Market_Center.getHQNodeData?page=1&num=40&sort=symbol&asc=1&node=sw1_650000&symbol=&_s_r_a=init'
headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36 Edg/112.0.1722.39',
           'cookie': 'SINAGLOBAL=112.86.96.156_16271.9594; SCF=AlO7tPI5YrVX8m0dg5Q2qN5k-Q-3R2u8ZxlEBgCu-adlIFs_iy3-wvvaWI_iBOgGM60RBECC5aOGSdviEWg0.; U_TRS1=00000a0.c5673618.613c1ff5.acffbbc1; SGUID=1638090492543_3970731; FSINALOBAL=112.917.146_162739391.9554; UOR=,,; __bid_n=185ef2af6e3339e9c14207 FPTOKEN=cxKlwt1cjfLNeQxv5JFcGEu3x/mCYdciN/SRpn9C/57vDUnX/otJQ4/rfC0I9H7DuQZ6cQ0EVTw5n3XWw88WuBVp34KWntO0OGOL3/BWVhWenlZEiRwsi3ooa1MXTIrT0RHi3iAwFM35qzWM7AqY6wcfH8zBfFUfgWVoYNydGkq0jNWR1mSuxL+n/GGxMnouGPdpEIqnskVCpu1eZmxpRsdgdGFdufV87pnIPkWjSlRTtuL3nEDydYZgtLI0o4f/Tz2cK1cORhsS01ER5cihUINWFpPWN6V9KtcQ+EW7y8dblBlHLDoC837ZY3cdjZTEVe/u1NYiK+nv7JZ2KiuyjtbQ44KsM4JWX+YHjZrEnlMkxEOxlI+CcXWHYONOiq9XotAyVVaVs3Tg==|Ub5zrecyikK3Z8iJHUvLCMpOomP7Ro6Pmw5tv+sAmZI=|10|37070689b3c1f599e217fd098c56bbfc; Hm_lvt_b82ffdf7cbc70caaacee097b04128ac1=1674754850; SUB=_2AkMUjjRNf8NxqwJRmfsWz3rYR1g_EieKi0sWWJRMyHRl-yD9kql4htRB6Pw4aoguODOQPrEdZ4T4WPJh11FvemoV; SR_SEL=1_511; FINA_V_S_2=sz000001,sh603282; Apache=120.85.187.132_168555452.7554; MONEYFINANCE-SINA-COM-CN-WEB5=; ULV=1681555411117:8:2:2:120.75.17.132_16815554.575554:168555405755'}
params = {'page': '1',
'num': '40',
'sort': 'symbol',
'asc': '1',
'node': 'sw1_650000',
'symbol': '',
'_s_r_a': 'init'}

req = requests.get(url=web,headers=headers)
print(type(req.text))
print(req.text)
图13 结果

       可以成功地获取到数据,但是打印数据的类型发现,数据类型为str字符串型,想要像字典和列表一样去提取数据,必须用json库把它转为列表或字典对象。

ls = req.json()
for line in ls:
    print(line)
    print('-'*70)
图14

        把每一行存到excel中,需要有一定的pandas基础,这里我就不一一讲了。有兴趣的可以学一下pandas。

df = pd.DataFrame()
ls = req.json()
for line in ls:
    df_li = pd.DataFrame(pd.Series(line))
    df = pd.concat([df,df_li.T],ignore_index=True)
df

 保存excel文件:

df.to_excel(r"C:\Users\流光、月影\Desktop\gp.xlsx",index=False)

结尾

        requests库有优点也有缺点,优点是简单,缺点是上面提到过的cookie过期问题,那是不是没有更好的方法了呢?答案是否的,还有个selenium库,直接写代码去驱动浏览器,可以解决cookie的问题,但是比较复杂,有兴趣的伙伴可以了解一下。

        爬虫不是一个独立的知识点,python任何一个东西都不是独立的,都是相互关联的,就如爬虫爬到的东西需要保存到电脑,那也是另外一个东西了,如 time 让程序等待,如 os 与系统交互,如 pandas、openpyxl 把数据写入表格等。如果不会保存数据,那么爬虫也毫无意义。学python都是循序渐进,慢慢来,一个一个地学,在这还有很长的路要走,每天学一点,终能登峰。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值