本次学习的教学视频来自嵩天老师的网络爬虫教学,主要学习内容有requests\BeautifulSoup\scrapy\re,目前除了scrapy其他刚好看完。并搬运实现了一些小项目如58同城租房信息爬取、淘宝搜索商品项目,现将从爬虫基本方法、实战和遇到的问题三个方面进行总结。

1.基本方法

首先就是requests库,是python最简易实用的HTTP库,是一个请求库。主要方法如下,其中requests.request()方法最常用,用于构造请求,是其他几种方法的总和。其余方法如get()获取HTML网页,head()获取网页head标签,post()\pu()t用于提交对应请求,patch()进行局部修改,delete()提交删除请求。

着重介绍request.get()方法,requests.get(url, params=None,**kwargs)

其中url为页面链接,params为额外参数,字典格式,**kwargs包含了12个控制访问的参数。(params\data\json\headers\cookies\auth\files\timeout\proxies\allow_redirects\stream\verify\cert)

通常我们使用get()方法获取页面的内容。

接着介绍请求得到的Response对象,见下表。

补充几段常用代码。

(1)爬取京东商品

import requests
url = "https://item.jd.com/2967929.html"
try:r = requests.get(url)r.raise_for_status()   #如果发送了错误请求,可以抛出异常r.encoding = r.apparent_encoding  #把文本内容的编码格式传递给头文件编码格式print(r.text[:1000])
except:print("爬取失败!")

(2)爬取亚马逊,需要修改headers字段,模拟请求

import requests
url="https://www.amazon.cn/gp/product/B01M8L5Z3Y"
try:kv = {'user-agent':'Mozilla/5.0'}  #模拟请求头r=requests.get(url,headers=kv)r.raise_for_status()r.encoding=r.apparent_encodingprint(r.status_code)print(r.text[:1000])
except:print("爬取失败")

(3)百度搜索关键词提交-params提交关键词

import requests
url="http://www.baidu.com/s"
try:kv={'wd':'Python'}r=requests.get(url,params=kv)print(r.request.url)r.raise_for_status()print(len(r.text))print(r.text[500:5000])
except:print("爬取失败")

(4)图片爬取存储

import requests
import os
url="http://tc.sinaimg.cn/maxwidth.800/tc.service.weibo.com/p3_pstatp_com/6da229b421faf86ca9ba406190b6f06e.jpg"
root="D://pics//"
path=root + url.split('/')[-1]
try:if not os.path.exists(root):os.mkdir(root)if not os.path.exists(path):r = requests.get(url)with open(path, 'wb') as f:f.write(r.content)   #r.content为图片f.close()print("文件保存成功")else:print("文件已存在")
except:print("爬取失败")

下面介绍BeautifulSoup库,用于对网页内容进行解析。

BeautifulSoup(mk, 'html.parser'),可以用html.parser\lxml\xml\html5lib作为解析器,这里选取html.parser。

元素主要有Tag\Name\Attributes\NavigableString\Comment。其中Tag使用方法如(soup.a),attrs使用如(a.attrs['class']),Navigable(tag.string)为非属性字符串,comment即注释。

标签树的遍历方法有(上行遍历、下行遍历、平行遍历)

此外可以用soup.prettify()输出有层次感的段落。

信息提取方法如下:常用find_all,具体对标签搜索有soup.find_all('a'),对属性搜索有soup.find_all('p',class='course'),对字符串搜索有soup.find_all(string='...'),配合正则表达式检索有soup.find_all(re.compile('link'))。

       find() 搜索且返回一个结果,字符串类型find_parents() 在先辈节点中搜索,返回一个列表类型find_parent() 在先辈节点中返回一个结果,字符串类型find_next_siblings() 在后续平行节点搜索,返回列表类型find_next_sibling()find_previous_siblings()find_previous_sibling() 在前序平行节点中返回一个结果,字符串类型find_all(name,attrs,recursive,string,**kwargs) 返回一个列表类型,存储查找的结果参数:name:对标签名称的检索字符串,可以使用列表查找多个标签,find_all(true)所有标签attrs:对标签属性值的检索字符串,可标注属性检索 例如find_all('a','href')recursive:是否对子孙所有节点搜索,默认值为true,false则值查找当前节点儿子的信息    string:<></>中字符串区域的检索字符串

最后介绍Re正则表达式库。

正则表达式限定符如下:

贪婪匹配指匹配的数据无限多,所谓的的非贪婪指的是匹配的次数有限多。一般情况下,非贪婪只要匹配1次。*、+限定符都是贪婪的,因为它们会尽可能多的匹配文字,只有在它们的后面加上一个?就可以实现非贪婪或最小匹配。

在re库中一般使用raw string类型即r'text'。其中遇到特殊字符需要 \ 加以转义。

方法如下

  re.search(pattern,string,flag=0)在一个字符串中搜索匹配正则表达式的第一个位置,返回match对象re.match() 在一个字符串的开始位置起匹配正则表达式,返回match对象 注意match为空re.findall()搜索字符串,一列表类型返回全部能匹配的子串re.split()将一个字符串按照正则表达式匹配结果进行分割,返回列表类型re.finditer() 搜索字符串,返回一个匹配结果的迭代类型,每个迭代元素是match对象re.sub()在一个字符串中替换所有匹配正则表达式的子串,返回替换后的字符串re.compile(pattern,flags) 将正则表达式的字符串形式编译成正则表达式对象

flag = 0中有三种选择类型,re.I忽略大小写、re.M从每行开始匹配、re.S匹配所有字符。

以上是函数式用法,此外还有面向对象用法。

pat = re.compile('')
pat.search(text)

最后介绍match对象的属性和方法,见下。

  1、属性1)string 待匹配文本2)re 匹配时使用的pattern对象(正则表达式)3)pos 正则表达式搜索文本的开始位置4)endpos 正则表达式搜索文本的结束为止2、方法1).group(0) 获得匹配后的字符串2).start() 匹配字符串在原始字符串的开始位置3).end() 匹配字符串在原始字符串的结束位置4).span() 返回(.start(),.end())元组类型

2.实战演练

主要选取了淘宝商品搜索和58同城租房两个实例,链接分别为‘https://blog.csdn.net/u014135206/article/details/103216129?depth_1-utm_source=distribute.pc_relevant_right.none-task-blog-BlogCommendFromBaidu-8&utm_source=distribute.pc_relevant_right.none-task-blog-BlogCommendFromBaidu-8‘  'https://cloud.tencent.com/developer/article/1611414'

淘宝搜索

import requests
import redef getHTMLText(url):headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:70.0) Gecko/20100101 Firefox/70.0'}#cookies在元素审查,网络里面刷新,找请求头下面的Cookieusercookies = ''        #这里需要使用客户端的淘宝登录cookiescookies = {}for a in usercookies.split(';'):name, value = a.strip().split('=', 1)cookies[name] = valueprint(cookies)try:r = requests.get(url, headers=headers, cookies=cookies, timeout=60)r.raise_for_status()  #如果有错误返回异常print(r.status_code) #打印状态码r.encoding = r.apparent_encodingreturn r.textexcept:return 'failed'def parsePage(ilt, html):try:plt = re.findall(r'\"view_price\"\:\"[\d\.]*\"', html)tlt = re.findall(r'\"raw_title\"\:\".*?\"', html)for i in range(len(plt)):price = eval(plt[i].split(':')[1])  # 意义是进行分割其冒号title = eval(tlt[i].split(':')[1])ilt.append([price, title])except:print("")def printGoodsList(ilt):tplt = "{:4}\t{:8}\t{:16}"print(tplt.format("序号", "价格", "商品名称"))  # 输出信息count = 0for g in ilt:count = count + 1print(tplt.format(count, g[0], g[1]))def main():goods = '足球'depth = 3start_url = 'http://s.taobao.com/search?q={}&s='.format(goods)  # 找到起始页的url链接infoList = []for i in range(depth):  # 进行循环爬去每一页try:url = start_url + str(44 * i)html = getHTMLText(url)parsePage(infoList, html)except:continueprintGoodsList(infoList)main()

58同城爬取租房,这部分代码较多,选取重要内容展示。

1.加密字体的解码

# 获取字体文件并转换为xml文件
def get_font(page_url, page_num, proxies):response = requests.get(url=page_url, headers=headers, proxies=proxies)# 匹配 base64 编码的加密字体字符串base64_string = response.text.split("base64,")[1].split("'")[0].strip()# print(base64_string)# 将 base64 编码的字体字符串解码成二进制编码bin_data = base64.decodebytes(base64_string.encode())# 保存为字体文件with open('58font.woff', 'wb') as f:f.write(bin_data)print('第' + str(page_num) + '次访问网页,字体文件保存成功!')# 获取字体文件,将其转换为xml文件font = TTFont('58font.woff')font.saveXML('58font.xml')print('已成功将字体文件转换为xml文件!')return response.text# 将加密字体编码与真实字体进行匹配
def find_font():# 以glyph开头的编码对应的数字glyph_list = {'glyph00001': '0','glyph00002': '1','glyph00003': '2','glyph00004': '3','glyph00005': '4','glyph00006': '5','glyph00007': '6','glyph00008': '7','glyph00009': '8','glyph00010': '9'}# 十个加密字体编码unicode_list = ['0x9476', '0x958f', '0x993c', '0x9a4b', '0x9e3a', '0x9ea3', '0x9f64', '0x9f92', '0x9fa4', '0x9fa5']num_list = []# 利用xpath语法匹配xml文件内容font_data = etree.parse('./58font.xml')for unicode in unicode_list:# 依次循环查找xml文件里code对应的nameresult = font_data.xpath("//cmap//map[@code='{}']/@name".format(unicode))[0]# print(result)# 循环字典的key,如果code对应的name与字典的key相同,则得到key对应的valuefor key in glyph_list.keys():if key == result:num_list.append(glyph_list[key])print('已成功找到编码所对应的数字!')# print(num_list)# 返回value列表return num_list# 替换掉网页中所有的加密字体编码
def replace_font(num, page_response):# 9476 958F 993C 9A4B 9E3A 9EA3 9F64 9F92 9FA4 9FA5result = page_response.replace('鑶', num[0]).replace('閏', num[1]).replace('餼', num[2]).replace('驋', num[3]).replace('鸺', num[4]).replace('麣', num[5]).replace('齤', num[6]).replace('龒', num[7]).replace('龤', num[8]).replace('龥', num[9])print('已成功将所有加密字体替换!')return result

2.租房信息爬取

# 提取租房信息
def parse_pages(pages):num = 0soup = BeautifulSoup(pages, 'lxml')# 查找到包含所有租房的li标签all_house = soup.find_all('li', class_='house-cell')for house in all_house:# 标题# title = house.find('a', class_='strongbox').text.strip()# print(title)# 价格price = house.find('div', class_='money').text.strip()price = str(price)print(price)# 户型和面积layout = house.find('p', class_='room').text.replace(' ', '')layout = str(layout)print(layout)# 楼盘和地址address = house.find('p', class_='infor').text.replace(' ', '').replace('\n', '')address = str(address)print(address)num += 1print('第' + str(num) + '条数据爬取完毕,暂停3秒!')time.sleep(3)with open('58.txt', 'a+', encoding='utf-8') as f:          #这里需encoding编码为utf-8,因网络读取的文本和写入的文本编码格式不一;a+继续在文本底部追加内容。f.write(price + '\t' + layout + '\t' + address + '\n')

3.由于58会封禁爬虫IP地址,还需要爬取ip进行切换。

def getiplists(page_num):  #爬取ip地址存到列表,爬取pages页proxy_list = []for page in range(1, page_num):url = "  "+str(page)r = requests.get(url, headers=headers)soup = BeautifulSoup(r.text, 'lxml')ips = soup.findAll('tr')for x in range(5, len(ips)):ip = ips[x]tds = ip.findAll("td")  #找到td标签ip_temp = 'http://'+tds[1].contents[0]+":"+tds[2].contents[0]  #.contents找到子节点,tag之间的navigable也构成了节点proxy_list.append(ip_temp)proxy_list = set(proxy_list)  #去重proxy_list = list(proxy_list)print('已爬取到'+ str(len(proxy_list)) + '个ip地址')return proxy_list通过更新proxies,作为参数更新到requests.get()中,可以一直刷新IP地址。proxies = {'http': item,'https': item,}

3.经验总结

期间遇到问题汇总如下:

1.大多数网站都需要模拟请求头,user-agent。

2.淘宝需要模拟cookies登陆,cookies信息可以在检查元素中找到。

3.这种方法只能爬取静态的网页,对于数据写入javascript的动态网页,还需要新的知识。

4.爬取过程中容易被封IP,需要在IP代理网站爬取IP地址,不断刷新IP地址。在get()方法中增加proxies参数即可。

5.58的价格字符串采用的加密的方式显示,需要解码。

6.写入文本时要用encoding='utf-8'编码,避免出错。

请查收,一份让你年薪突破20W的Python爬虫笔记!相关推荐

  1. 请查收,一份让你年薪突破20W的Python爬虫笔记

    本次主要学习内容有requests\BeautifulSoup\scrapy\re,目前除了scrapy其他刚好看完.并搬运实现了一些小项目如58同城租房信息爬取.淘宝搜索商品项目,现将从爬虫基本方法 ...

  2. python这个软件学会能做什么工作-学会Python真的有高收入?盯,请查收这份入坑指南...

    学会Python真的有高收入?盯,请查收这份入坑指南 2018-10-10 20:51:00 567点赞 6312收藏 186评论 小编注:想获得更多专属福利吗?金币加成.尊享众测.专属勋章.达人福利 ...

  3. 大学开学初计算机水平测试,请查收这份大学生开学攻略——

    原标题:请查收这份大学生开学攻略-- 恭喜你!马上要开始大学生活啦! 什么?你想要关于大学的建议? 早就准备好啦,快来看

  4. 树莓派又出新品了?请查收这份Pico入门指南!

    关注.星标公众号,直达精彩内容 2021年1月底的时候,树莓派基金会发布了一个重磅消息,推出了进军微控制器领域的树莓派Pico. 功能强劲,价格便宜的特性让Pico受到了全世界创客们的关注,这篇文章就 ...

  5. BERT模型超酷炫,上手又太难?请查收这份BERT快速入门指南!

    点击上方"AI遇见机器学习",选择"星标"公众号 重磅干货,第一时间送达 来自 | GitHub    作者 | Jay Alammar 转自 | 机器之心 如 ...

  6. BERT模型超酷炫,上手又太难?请查收这份BERT快速入门指南

    2019-12-31 10:50:59 选自GitHub 作者:Jay Alammar 参与:王子嘉.Geek AI 如果你是一名自然语言处理从业者,那你一定听说过最近大火的 BERT 模型.本文是一 ...

  7. 叮!请查收本周份「知识图谱」专题论文解读

    本期内容选编自微信公众号「开放知识图谱」. TKDE ■ 链接 | https://www.paperweekly.site/papers/2194 ■ 解读 | 花云程,东南大学博士,研究方向为自然 ...

  8. 厌倦了Windows却买不起Mac?请查收这份Linux版本选择指南

    整理 | 彭慧中 责编 | 屠敏 出品 | CSDN(ID:CSDNnews) 世界上不存在一套适合所有人的完美操作系统.或许,风行多年的 Windows 已经让许多人产生审美疲劳了,而 Mac 系列 ...

  9. 这里有一份面筋请查收(四)

    这里我连续介绍三家公司的面试,一家是只有一面,还有两家是面完一面就没去了,没去主要是当时一周面了6家而且是在不同的城市,就选择性的挑了这两家没去,是在是太累了,6月17日那天嗓子都面哑了. 第一家(2 ...

最新文章

  1. 模板 - 二分图(包含全套常用定理性质)
  2. python输出等腰三角形代码_酷呆了!Python开发web应用的一些中级技巧
  3. 数学建模学习笔记——数学规划
  4. php布尔类型代码,php中的boolean(布尔)类型详解
  5. 【原】基础篇:第一篇,本节主要向大家介绍Ext的最基础的话题
  6. Android---AlarmManager(全局定时器/闹钟)指定时长或以周期形式执行某项操作
  7. MSP432P401R TI Drivers 库函数学习笔记(八)ADC
  8. python内置模块~shutil
  9. Linux 命令(114)—— nl 命令
  10. 修改pip下载存放和安装位置
  11. 信息学奥赛一本通1220
  12. 江西省萍乡市谷歌高清卫星地图下载
  13. 元宇宙的时代来不及解释了快上车
  14. 机器人系统设计(五)
  15. html5写自我介绍,一分钟标签式自我介绍4篇
  16. freesurfer recon-all并行运算parallel
  17. React+dva多图片上传
  18. MySQL数据库课程设计_Wincc实现与数据库的交互以及报表的实现方式
  19. 关于NdFeB样品的测量阶段总结
  20. NCBI|宏基因组原始数据上传

热门文章

  1. python-字典-定义-增删改取
  2. mac的safari浏览器调试h5
  3. 十一、python生成器和迭代器
  4. python 项目环境包的名称和版本导出和导入
  5. 13.Axis创建webservice客户端和服务端
  6. ORACLE 查询所有用户调度作业
  7. C# 实现连连看功能
  8. 12-1。。。面试的一些体会吧
  9. Day4_代码重用与函数
  10. 无法推动项目起步?试试麦当劳理论