python基础之爬虫入门


Posted in Python onMay 10, 2021

前言

python基础爬虫主要针对一些反爬机制较为简单的网站,是对爬虫整个过程的了解与爬虫策略的熟练过程。
爬虫分为四个步骤:请求,解析数据,提取数据,存储数据。本文也会从这四个角度介绍基础爬虫的案例。

一、简单静态网页的爬取

我们要爬取的是一个壁纸网站的所有壁纸

http://www.netbian.com/dongman/

python基础之爬虫入门

1.1 选取爬虫策略——缩略图

首先打开开发者模式,观察网页结构,找到每一张图对应的的图片标签,可以发现我们只要获取到标黄的img标签并向它发送请求就可以得到壁纸的预览图了。

python基础之爬虫入门

随后注意到网站不止一页,打开前3页的网站观察url有没有规律

http://www.netbian.com/dongman/index.htm#第一页
http://www.netbian.com/dongman/index_2.htm#第二页
http://www.netbian.com/dongman/index_3.htm#第三页

我们发现除了第一页其他页数的url都是有着固定规律的,所以先构建一个含有所有页数url的列表

url_start = 'http://www.netbian.com/dongman/'
url_list=['http://www.netbian.com/dongman/index.htm']
if not os.path.exists('./exercise'):
    os.mkdir('./exercise')
for i in range(2,133):
    url = url_start+'index_'+str(i)+'.htm'
    url_list.append(url)

至此我们的基本爬虫策略就确定了。

网页请求

for url in url_list:
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36'
    }
    response = requests.get(url=url,headers=headers).text

解析数据

在这里我们选用etree解析数据

tree = etree.HTML(response)

提取数据

在这里我们选用xpath提取数据

leaf = tree.xpath('//div[@class="list"]//ul/li/a/img/@src')
for l in leaf:
      print(l)
      h = requests.get(url=l, headers=headers).content

存储数据

i = 'exercise/' + l.split('/')[-1]
with open(i, 'wb') as fp:
      fp.write(h)

完整代码

import requests
from lxml import etree
import os
url_start = 'http://www.netbian.com/dongman/'
url_list=['http://www.netbian.com/dongman/index.htm']
#http://www.netbian.com/dongman/index_2.htm
if not os.path.exists('./exercise'):
    os.mkdir('./exercise')
for i in range(2,133):
    url = url_start+'index_'+str(i)+'.htm'
    url_list.append(url)
print(url_list)
for url in url_list:
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36'
    }
    response = requests.get(url=url,headers=headers).text
    tree = etree.HTML(response)
    leaf = tree.xpath('//div[@class="list"]//ul/li/a/img/@src')
    for l in leaf:
        print(l)
        h = requests.get(url=l, headers=headers).content
        i = 'exercise/' + l.split('/')[-1]
        with open(i, 'wb') as fp:
            fp.write(h)

1.2 选取爬虫策略——高清大图

在刚刚的爬虫中我们爬取到的只是壁纸的缩略图,要想爬到高清版本,就需要我们更改策略。重新打开开发者工具进行观察,发现在原先爬取的img标签之上还有一个href标签,打开之后就会跳转高清大图。

python基础之爬虫入门
python基础之爬虫入门

那么此时我们的爬取策略就变成了提取这个href标签的内容,向这个标签中的网站发送请求,随后在该网站中找到img标签进行再一次请求。

我们用到了正则表达式来提取href标签的内容。正则表达式是比xpath语法更简便的一种数据提取方法,具体有关语法可查看以下文档

for url in url_list:
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36'
    }
    response = requests.get(url=url,headers=headers).text
    leaf = re.findall("desk/\d*.htm",response,re.S)
    for l in leaf:
        url = "http://www.netbian.com/"+str(l)
        h = requests.get(url=url, headers=headers).text
        leaf_ =re.findall('<div class="pic">.*?(http://img.netbian.com/file/\d*/\d*/\w*.jpg)',h,re.S)

这样输出的leaf_就是我们要找的高清大图的img标签,此时我们只需要再次发送请求随后再保存数据就可以了。

存储数据

for l_ in leaf_:
      print(l_)
      h = requests.get(url=l_, headers=headers).content
      i = 'exercise/' + l_.split('/')[-1]
      with open(i, 'wb') as fp:
          fp.write(h)

完整代码

import requests
import os
import re
url_start = 'http://www.netbian.com/dongman/'
url_list=['http://www.netbian.com/dongman/index.htm']
if not os.path.exists('./exercise'):
    os.mkdir('./exercise')
for i in range(2,133):
    url = url_start+'index_'+str(i)+'.htm'
    url_list.append(url)
print(url_list)
for url in url_list:
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36'
    }
    response = requests.get(url=url,headers=headers).text
    leaf = re.findall("desk/\d*.htm",response,re.S)
    for l in leaf:
        url = "http://www.netbian.com/"+str(l)
        h = requests.get(url=url, headers=headers).text
        leaf_ =re.findall('<div class="pic">.*?(http://img.netbian.com/file/\d*/\d*/\w*.jpg)',h,re.S)
        for l_ in leaf_:
            print(l_)
            h = requests.get(url=l_, headers=headers).content
            i = 'exercise/' + l_.split('/')[-1]
            with open(i, 'wb') as fp:
                fp.write(h)

二、动态加载网站的爬取

我们要爬取的是另一个壁纸网站的所有壁纸

https://sucai.gaoding.com/topic/9080?

python基础之爬虫入门

2.1 选取爬虫策略——selenium

首先打开开发者模式,观察网页结构,此时我们会发现一页上的所有壁纸并不是全部都加载出来了的,也就是说随着我们下拉滚动条,内容会不断实时加载出来,查看网页元素时也能看到lazy-image这个代表动态加载的标签

python基础之爬虫入门

由于是动态加载,因此不能用之前的直接发送请求的办法来爬取数据了,面对这种情况我们就需要模拟浏览器发送一个请求,并且下拉页面,来实现爬取一个实时加载网页的目的。

观察完网页结构之后我们又来观察页数,这次就不多说了,想必大家也能发现规律

url_list=[]
for i in range(1,4):
    url =  'https://sucai.gaoding.com/topic/9080?p={}'.format(i)
    url_list.append(url)

网页请求

在这里我们用到了selenium这个自动化测试框架

for url in url_list:
    driver = webdriver.Chrome()
    driver.get(url)
    driver.maximize_window()
    time.sleep(2)
    i=0
    while i<10:#下拉滚动条加载页面
        i+=1
        driver.execute_script("window.scrollBy(0,500)")
        driver.implicitly_wait(5)#显式等待

解析提取数据

items = driver.find_elements_by_xpath("//*[@class='gdd-lazy-image__img gdd-lazy-image__img--loaded']")
    for item in items:
            href = item.get_attribute('src')
            print(href)

至于数据的存储只需要再请求我们爬下来的href标签的网站就可以了。

完整代码

from selenium import webdriver
import time
import os
if not os.path.exists('./exercise'):
    os.mkdir('./exercise')
headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.75 Safari/537.36'
    }
url_list=[]
url_f_list=[]
for i in range(1,4):
    url =  'https://sucai.gaoding.com/topic/9080?p={}'.format(i)
    url_list.append(url)
for url in url_list:
    driver = webdriver.Chrome()
    driver.get(url)
    driver.maximize_window()
    time.sleep(2)
    i=0
    while i<10:
        i+=1
        driver.execute_script("window.scrollBy(0,500)")
        driver.implicitly_wait(5)#显式等待
    items = driver.find_elements_by_xpath("//*[@class='gdd-lazy-image__img gdd-lazy-image__img--loaded']")
    for item in items:
            href = item.get_attribute('src')
            print(href)

2.2 选取爬虫策略——api

众所周知,api接口是个好东西,如果找到了它,我们就无需担心动态加载,请求api返回给我们的是json格式的字典,里面或许有我们需要的东西也说不定。那么我们重新打开开发者工具搜索一番吧!

python基础之爬虫入门

从Element切换到Network我们可以发现这里多了好多奇怪的东西,但是打开preview好像没有我们能用到的。

这个时候别灰心,切换下页面,等第二页加载出来的时候最后又多出来了一个xhr文件,点开preview我们惊喜的发现,这个里面有每一张图id的信息!

python基础之爬虫入门

搜寻一圈发现字典里有效的只有id这个值,那么id对于我们的图片爬取有什么意义呢?通常情况下网址+id就可以定位到具体的图片,于是我点进去一张壁纸,惊喜的发现跟我想的一样!

python基础之爬虫入门

最后又到了我们老生常谈的页数环节,在看到这个api的request url之后大家有没有观察到它其中带着page_num=2&page_size=100这两个看着很像页码的参数呢?我们再往下就看到了参数中也正好有这两个值!也就是说我们只需要更改page_num=2就可以实现翻页了!

python基础之爬虫入门

url='https://api-sucai.gaoding.com/api/csc-api/topics/9080/modules/18928/templets?'
headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36'
    }
params_list=[]
for i in range(1,4):
    parms ={
        'page_num': i,
        'page_size': 100
    }
    params_list.append(parms)

解析提取数据

for param in params_list:
    response = requests.get(url=url,params=param,headers=headers).json()
    for i in range(100):
        try:
            dict  =response[i]
            id = dict['id']
            url_f = 'https://sucai.gaoding.com/material/'+str(id)
            url_f_list.append(url_f)
        except:
            pass

存储数据

for l in url_f_list:
    print(l)
    h = requests.get(url=l, headers=headers).content
    i = 'exercise/' + l.split('/')[-1]
    with open(i, 'wb') as fp:
        fp.write(h)

完整代码

import os
import requests
if not os.path.exists('./exercise'):
    os.mkdir('./exercise')
url='https://api-sucai.gaoding.com/api/csc-api/topics/9080/modules/18928/templets?'
headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36'
    }
params_list=[]
url_f_list=[]
for i in range(1,4):
    parms ={
        'page_num': i,
        'page_size': 100
    }
    params_list.append(parms)
for param in params_list:
    response = requests.get(url=url,params=param,headers=headers).json()
    for i in range(100):
        try:
            dict  =response[i]
            id = dict['id']
            url_f = 'https://sucai.gaoding.com/material/'+str(id)
            url_f_list.append(url_f)
        except:
            pass
for l in url_f_list:
    print(l)
    #h = requests.get(url=l, headers=headers).content
    #i = 'exercise/' + l.split('/')[-1]
    #with open(i, 'wb') as fp:
    #    fp.write(h)

三、selenium模拟登录

我们要爬取的网站总是免不了登录这一关键环节,因此模拟登录也是一大爬虫基础。
我们要模拟登录的网站如下

https://www.icourse163.org/course/BIT-268001

python基础之爬虫入门

选取爬虫策略

既然我们是用selenium模拟登陆,首先肯定要明确我们要模拟的具体内容,归纳起来就是

点击 登录|注册
点击 其他登陆方式
点击 手机号登录
输入账号
输入密码
点击 登录

在明确该干些什么之后我们就打开开发者模式观察一下这个登录框吧。

python基础之爬虫入门

不看不知道,一看吓一跳,原来这里有一个iframe框架,这就意味着如果我们不做任何处理就查找元素的话可能会什么都查找不到。这就相当于在王家找李家的东西一样,我们首先需要切换到当前iframe

driver.switch_to.frame(driver.find_element_by_xpath('//*[@id="j-ursContainer-1"]/iframe'))

经过这一操作之后我们就可以正常按部就班的进行模拟登陆了!

完整代码

from selenium import webdriver
import time
url = 'https://www.icourse163.org/course/BIT-268001'
driver = webdriver.Chrome()
driver.get(url)
driver.maximize_window()
#time.sleep(2)
driver.find_element_by_xpath('//div[@class="unlogin"]/a').click()
driver.find_element_by_class_name('ux-login-set-scan-code_ft_back').click()
driver.find_element_by_xpath('//ul[@class="ux-tabs-underline_hd"]/li[2]').click()
driver.switch_to.frame(driver.find_element_by_xpath('//*[@id="j-ursContainer-1"]/iframe'))
driver.implicitly_wait(2)#给登录框一些加载的时间
driver.find_element_by_css_selector('input[type="tel"]').send_keys('15201359153')
driver.find_element_by_css_selector('input[class="j-inputtext dlemail"]').send_keys('Asdasd123')
driver.implicitly_wait(2)#如果不等待的话可能密码还没输入结束就点按登录键了
driver.find_element_by_id('submitBtn').click()

到此这篇关于python基础之爬虫入门的文章就介绍到这了,更多相关python入门爬虫内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python的常见命令注入威胁
Feb 18 Python
python比较2个xml内容的方法
May 11 Python
Python文件夹与文件的相关操作(推荐)
Jul 25 Python
Eclipse和PyDev搭建完美Python开发环境教程(Windows篇)
Nov 16 Python
Python读取指定目录下指定后缀文件并保存为docx
Apr 23 Python
无法使用pip命令安装python第三方库的原因及解决方法
Jun 12 Python
selenium+python自动化测试之环境搭建
Jan 23 Python
python自动化之Ansible的安装教程
Jun 13 Python
django 消息框架 message使用详解
Jul 22 Python
python实现的自动发送消息功能详解
Aug 15 Python
python 8种必备的gui库
Aug 27 Python
详解Anaconda 的安装教程
Sep 23 Python
python设置 matplotlib 正确显示中文的四种方式
提取视频中的音频 Python只需要三行代码!
Python-typing: 类型标注与支持 Any类型详解
May 10 #Python
超详细Python解释器新手安装教程
Python机器学习三大件之一numpy
python实现自动清理文件夹旧文件
May 10 #Python
Python中的min及返回最小值索引的操作
May 10 #Python
You might like
分页显示Oracle数据库记录的类之一
2006/10/09 PHP
探讨PHP函数ip2long转换IP时数值太大产生负数的解决方法
2013/06/06 PHP
Yii入门教程之Yii安装及hello world
2014/11/25 PHP
php获取网页上所有链接的方法
2015/04/03 PHP
PHP编程获取图片的主色调的方法【基于Imagick扩展】
2017/08/02 PHP
javascript开发技术大全-第3章 js数据类型
2011/07/03 Javascript
addEventListener 的用法示例介绍
2014/05/07 Javascript
jquery验证邮箱格式并显示提交按钮
2015/11/07 Javascript
为jQuery-easyui的tab组件添加右键菜单功能的简单实例
2016/10/10 Javascript
5种JavaScript脚本加载的方式
2017/01/16 Javascript
BootStrap select2 动态改变值的方法
2017/02/10 Javascript
Js实现中国公民身份证号码有效性验证实例代码
2017/05/03 Javascript
VUE2 前端实现 静态二级省市联动选择select的示例
2018/02/09 Javascript
使用xampp将angular项目运行在web服务器的教程
2019/09/16 Javascript
Vue 组件复用多次自定义参数操作
2020/07/27 Javascript
ant design vue嵌套表格及表格内部编辑的用法说明
2020/10/28 Javascript
jquery实现点击左右按钮切换图片
2021/01/27 jQuery
用map函数来完成Python并行任务的简单示例
2015/04/02 Python
python画双y轴图像的示例代码
2019/07/07 Python
Django 数据库同步操作技巧详解
2019/07/19 Python
Python如何使用字符打印照片
2020/01/03 Python
基于python实现FTP文件上传与下载操作(ftp&amp;sftp协议)
2020/04/01 Python
HTML5 video循环播放多个视频的方法步骤
2020/08/06 HTML / CSS
潘多拉珠宝英国官方网上商店:PANDORA英国
2018/06/12 全球购物
Brora官网:英国领先的羊绒服装品牌
2019/08/28 全球购物
英国家居装饰品、户外家具和玻璃器皿购物网站:Rinkit.com
2019/11/04 全球购物
运动会邀请函范文
2014/01/31 职场文书
大学生学习2014年全国两会心得体会
2014/03/12 职场文书
金融管理专业求职信
2014/07/10 职场文书
2014年服装销售工作总结
2014/11/27 职场文书
2016班级元旦联欢会开幕词
2016/03/04 职场文书
写好求职信的技巧解密
2019/05/14 职场文书
为什么node.js不适合大型项目
2021/04/28 Javascript
linux下导入、导出mysql数据库命令的实现方法
2021/05/26 MySQL
python编程实现清理微信重复缓存文件
2021/11/01 Python
Python中三种花式打印的示例详解
2022/03/19 Python