新手怎么学习python爬虫,如何实现简单的python爬虫
Admin 2022-06-11 群英技术资讯 548 次浏览
python基础爬虫主要针对一些反爬机制较为简单的网站,是对爬虫整个过程的了解与爬虫策略的熟练过程。
爬虫分为四个步骤:请求,解析数据,提取数据,存储数据。本文也会从这四个角度介绍基础爬虫的案例。
我们要爬取的是一个壁纸网站的所有壁纸
http://www.netbian.com/dongman/
首先打开开发者模式,观察网页结构,找到每一张图对应的的图片标签,可以发现我们只要获取到标黄的img标签并向它发送请求就可以得到壁纸的预览图了。
随后注意到网站不止一页,打开前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)
在刚刚的爬虫中我们爬取到的只是壁纸的缩略图,要想爬到高清版本,就需要我们更改策略。重新打开开发者工具进行观察,发现在原先爬取的img标签之上还有一个href标签,打开之后就会跳转高清大图。
那么此时我们的爬取策略就变成了提取这个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?
首先打开开发者模式,观察网页结构,此时我们会发现一页上的所有壁纸并不是全部都加载出来了的,也就是说随着我们下拉滚动条,内容会不断实时加载出来,查看网页元素时也能看到lazy-image这个代表动态加载的标签。
由于是动态加载,因此不能用之前的直接发送请求的办法来爬取数据了,面对这种情况我们就需要模拟浏览器发送一个请求,并且下拉页面,来实现爬取一个实时加载网页的目的。
观察完网页结构之后我们又来观察页数,这次就不多说了,想必大家也能发现规律
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)
众所周知,api接口是个好东西,如果找到了它,我们就无需担心动态加载,请求api返回给我们的是json格式的字典,里面或许有我们需要的东西也说不定。那么我们重新打开开发者工具搜索一番吧!
从Element切换到Network我们可以发现这里多了好多奇怪的东西,但是打开preview好像没有我们能用到的。
这个时候别灰心,切换下页面,等第二页加载出来的时候最后又多出来了一个xhr文件,点开preview我们惊喜的发现,这个里面有每一张图id的信息!
搜寻一圈发现字典里有效的只有id这个值,那么id对于我们的图片爬取有什么意义呢?通常情况下网址+id就可以定位到具体的图片,于是我点进去一张壁纸,惊喜的发现跟我想的一样!
最后又到了我们老生常谈的页数环节,在看到这个api的request url之后大家有没有观察到它其中带着page_num=2&page_size=100这两个看着很像页码的参数呢?我们再往下就看到了参数中也正好有这两个值!也就是说我们只需要更改page_num=2就可以实现翻页了!
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)
我们要爬取的网站总是免不了登录这一关键环节,因此模拟登录也是一大爬虫基础。
我们要模拟登录的网站如下
https://www.icourse163.org/course/BIT-268001
选取爬虫策略
既然我们是用selenium模拟登陆,首先肯定要明确我们要模拟的具体内容,归纳起来就是
点击 登录|注册
点击 其他登陆方式
点击 手机号登录
输入账号
输入密码
点击 登录
在明确该干些什么之后我们就打开开发者模式观察一下这个登录框吧。
不看不知道,一看吓一跳,原来这里有一个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()
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
这篇文章主要为大家详细介绍了Python实现双向链表基本操作,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
这个名为PyScript的框架,其核心目标是为开发者提供在标准HTML中嵌入Python代码的能力,使用 Python调用JavaScript函数库,并以此实现利用Python创建Web应用的功能,本文给大家介绍Python HTML运行的案例解析,感兴趣的朋友一起看看吧
在实际工作中,经常涉及到数据的传递。这篇文章主要为大家介绍了Python的一些基础学习:深拷贝与浅拷贝问题、递归函数的练习,需要的朋友可以参考一下
__init__()一般用来创建对象的实例变量,或一次性操作,super()用于调用父类的方法,可用来解决多重继承问题,下面这篇文章主要给大家介绍了关于Python中super().__init__()测试及理解的相关资料,需要的朋友可以参考下
本篇文章给大家带来了关于Python的相关知识,其中主要为大家介绍了Python遗传算法Geatpy工具箱使用介绍,有需要的朋友可以借鉴参考下,希望能够有所帮助,下面一起来看一下。
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008