前言:本人很菜,学习很泛。
个人博客文章原地址,阅读更加美观

由于参加数学建模的需要,在这个寒假期间小学了一下爬虫(Python学习),想着我记性这么差,还是得对这段时间的学习进行整理,以防忘记。

一、爬虫介绍

网络爬虫又称网络蜘蛛、网络机器人,是指按照某种规则在网络上爬取所需内容的脚本程序。每个网页通常包含其他网页的入口和大量信息,网络爬虫则是进入网页,定位获取所需内容。

爬虫可以划分为以下三步:

  1. 爬取网页
  2. 解析数据
  3. 保存数据

其中最重要的应该是解析数据这部分,因为这部分编写对应的代码来定位html内容,从而获取我们想要爬取的数据。爬取部分可以通过urllib模块进行获取网页的html代码。保存数据,主要有两种方法,一种是直接保存进Excel,另一种是更面向系统,保存进数据库。我学习的过程使用的是SQLite数据库引擎,小型,方便。特别是运用Pycharm中dataset工具包,使得数据库运用起来是十分的方便。


二、爬取网页

平常登入浏览器上网,最频繁使用的两种请求是get请求和post请求。get请求输入的数据是直接显示在url上,安全性不够。post请求数据是不显示在url上,安全性比较高。(就比如输入密码,是直接在网页上输入,而不是写入url中)

下面代码是get和post请求和返回响应

httpbin.org是一个专门用于爬虫测试的网站

get请求

import urllib.request
response = urllib.request.urlopen('http://httpbin.org/get')
print(response.read().decode('utf-8'))#响应内容
{"args": {}, "headers": {"Accept-Encoding": "identity", "Host": "httpbin.org", "User-Agent": "Python-urllib/3.9", "X-Amzn-Trace-Id": "Root=1-61f3ef09-6616eeab295d5103700d9757"}, "origin": "112.50.41.143", "url": "http://httpbin.org/get"
}

post请求

data = bytes(urllib.parse.urlencode({"hellow":"world"}), encoding='utf-8')
response = urllib.request.urlopen('http://httpbin.org/post', data=data)
print(response.read().decode('utf-8'))#响应内容
{"args": {}, "data": "", "files": {}, "form": {"hellow": "world"}, "headers": {"Accept-Encoding": "identity", "Content-Length": "12", "Content-Type": "application/x-www-form-urlencoded", "Host": "httpbin.org", "User-Agent": "Python-urllib/3.9", "X-Amzn-Trace-Id": "Root=1-61f3f1af-3c727e890ee174572c7b86fd"}, "json": null, "origin": "112.50.41.143", "url": "http://httpbin.org/post"
}

从上面的响应headers中,可以发现User-Agent的内容是Python-urllib/3.9,说明服务器端知道我们访问的环境,也就是说服务器知道我们在爬虫,对于一些设有安全性的网页会拒绝我们访问。

假如我们通过上述方式正常访问豆瓣网页,会发现出现了如下418警告。

response = urllib.request.urlopen(r'https://movie.douban.com')
print(response.read().decode('utf-8'))#警告
urllib.error.HTTPError: HTTP Error 418:

那么是不是说明设有安全性的网页就没法访问了,显然,大佬们如此智慧,肯定是有办法解决的。

通过代码伪装浏览器访问头,成功爬取。消息头headers的内容可以通过打开浏览器按F12键,随便点击一个get或post请求,查看消息头即可。以下以火狐浏览器截图为例:

伪装浏览器头消息代码如下:

url = r'https://movie.douban.com'
headers = {'User-Agent': r'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.9 Safari/537.36','Cookie': 'bid=7mM480uOFCo; dbcl2="252912187:UtqLjbzdBdY"; ck=6DJI; _pk_ref.100001.4cf6=["","",1642433569,"https://accounts.douban.com/"]; _pk_ses.100001.4cf6=*; __utma=30149280.116081932.1642433569.1642433569.1642433569.1; __utmc=30149280; __utmz=30149280.1642433569.1.1.utmcsr=accounts.douban.com|utmccn=(referral)|utmcmd=referral|utmcct=/; __utmz=223695111.1642433569.1.1.utmcsr=accounts.douban.com|utmccn=(referral)|utmcmd=referral|utmcct=/; __utmc=223695111; __utmb=223695111.0.10.1642433569; __utma=223695111.1563560722.1642433569.1642433569.1642433569.1; __gads=ID=c847fa157ddd2521-2202472700d0001e:T=1642433572:RT=1642433572:S=ALNI_Ma_fS0aJS2enPjG0sgam_fOP8ZAfA; push_doumail_num=0; push_noty_num=0; __utmt=1; __utmv=30149280.25291; __utmb=30149280.2.10.1642433569; _pk_id.100001.4cf6=b998428814f5d240.1642433569.1.1642434417.1642433569.; Hm_lvt_eaa57ca47dacb4ad4f5a257001a3457c=1642433569,1642433596,1642434417; Hm_lpvt_eaa57ca47dacb4ad4f5a257001a3457c=1642434417'
}req = urllib.request.Request(url=url, headers=headers)
response = urllib.request.urlopen(req)
print(response.read().decode('utf-8'))

返回的html部分代码如下:
接着,我们对返回的html进行处理,将我们想要爬取的内容整理提取出来。

三、解析数据

对数据进行解析提取,主要使用python的bs4库和正则表达式re库,bs4中的BeautifulSoup类封装处理html,方便定位到对应标签。

BeautifulSoup中最常用的.find_all(),可用于字符串、正则表达式、函数匹配。
将baidu.html存入目录下,并以baidu.html为检索目标,代码展示了各种定位方法,以实用为主。

BeatifulSoup

#各种提取数据的方式,《最好自己每个都试一下》,按需选择方法
from bs4 import BeautifulSoupfile = open('./baidu.html', 'rb')
html = file.read()bs = BeautifulSoup(html, 'html.parser')file = open('./baidu.html', 'rb')
html = file.read()bs = BeautifulSoup(html, 'html.parser')print(bs)               #html内容
print(bs.title)         #title内容
print(bs.a)             #标签a内容
print(bs.head)          #head内容
print(type(bs.head))    #head内容类型类
print(bs.title.string)  #只取title内容中标题部分
print(bs.a.attrs)       #标签a属性内容# 1.Tab 标签及其内容,第一个
# 2.NavigableString 标签里的内容
# 3.BeautifulSoup 整个文档
# 4.Comment 是一个特殊的NavigableString 输出内容不包括注释
print(type(bs))
print(bs.name)
print(bs.attrs)
print(bs)# -----------------------------------------
# 文档的遍历
print(bs.head.contents[1])# 文档的搜索
# (1)find_all
# 字符串过滤: 查找与字符串完全匹配的内容
t_list = bs.find_all('a')
print(t_list)# 正则表达式搜素: 使用search()方法匹配内容
t_list = bs.find_all(re.compile('a'))
print(t_list)# 方法: 传入一个函数,根据函数要求搜索 (了解)
def name_is_exists(tag):return tag.has_attr('name')t_list = bs.find_all(name_is_exists)
print(t_list)# (2)kwargs 参数
t_list = bs.find_all(id = "head")
t_list = bs.find_all(class_=True)# (3)text参数
t_list = bs.find_all(text='hao123')
t_list = bs.find_all(text=['hao123', '地图', '贴吧'])
t_list = bs.find_all(text=re.compile('\d')) #正则# (4)limit参数
t_list = bs.find_all('a', limit=3)# css选择器
t_list = bs.select('title') #标签
t_list = bs.select('.mnav')   #类名
t_list = bs.select('#u1')   #id
t_list = bs.select("a[class='bri']")   #属性
t_list = bs.select("head > title")   #子标签
t_list = bs.select(".mnav ~ .bri") #print(t_list[0].get_text())

baidu.html

<!DOCTYPE html>
<html>
<head><meta content="IE=Edge" http-equiv="X-UA-Compatible"/><meta content="always" name="referrer"/><link href="https://ss1.bdstatic.com/5eN1bjq8AAUYm2zgoY3K/r/www/cache/bdorz/baidu.min.css"rel="stylesheet" type ="text/css" />
<!--    具体显示的样式--><title>百度一下,你就知道啦</title>
</head>
<body link="#0000cc"><div id="wrapper"><div id="head"><div class="head_wrapper"><div id="u1"><a class="mnav" href="http://news.baidu.com" name="tj_trnews">!--新闻-</a><a class="mnav" href="http://news.baidu.com" name="tj_trnews">新闻</a><a class="mnav" href="https://www.hao123.com" name="tj_trhao123">hao123</a><a class="mnav" href="http:/ /map.baidu.com" name="tj_trmap">地图</a><a class="mnav" href="http://v.baidu.com" name="tj_trvideo">视频</a><a class="mnav" href="http://tieba.baidu.com" name="tj_trtieba">贴吧</a><a class="bri" href="//www.baidu.com/more/" name="tj_briicon" style="....">更多产品</a></div></div></div></div>
</body>
</html>

正则表达式主要用于定位那些比较泛型的内容,也是爬虫常常用到的,如提取网站邮箱,邮箱的后缀通常都一样,如QQ邮箱后缀为@qq.com,但是前部分都是各自的QQ号,所以可以利用正则表达式将所以QQ邮箱号码提取出来,非常实用。以下是我自认为比较常用的正则表达式方法,具体的网上很多:

字符 描述 实例
. 匹配除换行符 \n 之外的任何单字符
( ) 分组标记,内部只能使用 操作符
* 前一个字符0次或无限次扩展 abc*表示ab、abc、abcc、abccc等
+ 前一个字符一次或无限次扩展 abc+表示abc、abcc、abccc等
? 前一个字符0次或者1次扩展 abc?表示ab、abc
[ ] 字符集,对单个字符给出取值范围 [abc]表示a、b、c,[a-z]表示a到z单个字符
表达式左右任意一个
{m} 扩展前一个字符m次 ab{2}c表示abbc
{m,n} 扩展前一个字符m至n次 ab{1,2}c表示abc,abbc
^ 匹配字符串开头 ^abc表示abc且在一个字符串的开头
$ 匹配字符串结尾 abc$表示abc且在一个字符串的结尾
\d 数字,等价于[0-9]
\w 单词字符,等价于[A-Za-z0-9_]

正则表达式在Python用到是re库,里面提供各自种API对数据进行处理,以下我举例了几个简单的例子。

import repat = re.compile('AA') #此时的AA是正则表达式
m = pat.search('AACDBAA') #search字符串被校验的内容
print(m) #输入结果<re.Match object; span=(1, 3), match='AA'>m = re.search('asd','Aasd')
m = re.findall('a', 'ASDdadaSJJAa')
m = re.findall('[A-Z]+', 'ASDdaAdaSJJAa')
m = re.sub('a', 'A', 'adadfafs') #第一个被替换,第二个替换后,第三个对象
a = r'dafa\fafa/faf\fafaf\fasd\d\fx'
# print(m)

将正则表达式应用于html解析
如前面的baidu.html,假如我们需要类mnav的href内容,只需要如下代码,十分便利

import re
from bs4 import BeautifulSoupfile = open('./baidu.html', 'rb')
html = file.read()
bs = BeautifulSoup(html, 'html.parser')
findhref = re.compile(r'<a class="mnav" href="(.*?)"')
result = re.findall(findhref, str(bs))
print(result)

四、保存数据

主要用到xlwt(excel)和sqlite3(database)库,下面只介绍sqlite3。

sqlite是一个轻型的数据库,创建十分方便,只需要几行代码。适用于数据量不多的项目,对于爬虫是足够了。

#数据库的创建和初始化
def init_db(dbpath):sql = '''create table headImages(标题 varchar(20),日期 datatime,图片链接 text)'''conn = sqlite3.connect(dbpath)cursor = conn.cursor()cursor.execute(sql)conn.commit()conn.close()

其实对于数据库的各个sql语句的执行,都是直接通过游标cursor()执行,一行代码解决,没有什么困难。难的就是需要把所有的各个方方面面整合在一起,对于大多数项目其实都是这样,对于学习单个内容其实都蛮简单。

#insert into将数据插入table即可
def saveData2DB(dataList, dbpath):init_db(dbpath)conn = sqlite3.connect(dbpath)cur = conn.cursor()for data in dataList:for index in range(len(data)):data[index] = '"'+data[index]+'"'sql = '''insert into movie250(info_link,pic_link,cname,ename,score,rated,instroduction,info)values(%s)'''%','.join(data)# print(sql)cur.execute(sql)conn.commit()cur.close()conn.close()

实战

写了爬取头像的代码,并且根据自己喜好去爬。还没有做web可视化,做好就可以直接在网站上实时更新并选择自己喜欢的头像,有时间再做。爬取头像关键词[‘可爱’, ‘动漫’, ‘手绘’, ‘搞怪’],代码附excel保存版本。

代码可执行

# -- coding: utf-8 --
# @Author: zrs
# @Time: 2022-02-07 14:53
# @File: main.pyimport re
import xlwt
import sqlite3
import numpy as np
import urllib.request
from bs4 import BeautifulSoupurl = r'https://www.woyaogexing.com/touxiang/qinglv/'def askURL(url):headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:96.0) Gecko/20100101 Firefox/96.0','Cookie': 'BAIDU_SSP_lcr=https://www.baidu.com/link?url=pCdSJIVWq3oRa2SQ63p2b2G6MhUGFLwmqAr4tM9pP-HMoNZVYwtunks5FpRiI6X7&wd=&eqid=bc47740e0007c8de000000056200c13b; Hm_lvt_a077b6b44aeefe3829d03416d9cb4ec3=1643031884,1644216664,1644216690; __gads=ID=03cc11a055dcdbab-2294c11433d00095:T=1643031885:RT=1643031885:S=ALNI_MYbVQjpAjO2k9fH36n0Lkm_6gkiYA; Hm_lpvt_a077b6b44aeefe3829d03416d9cb4ec3=1644216740'}request = urllib.request.Request(url, headers=headers)html = ''try:response = urllib.request.urlopen(request)html = response.read().decode('utf-8')except urllib.error.URLError as e:if hasattr(e, 'code'):print(e.code)if hasattr(e, 'reason'):print(e.reason)return htmldef getData(base_html):soup = BeautifulSoup(base_html, 'html.parser')# print(soup)findHref = re.compile(r'<a class="img" href="(.*?)"')findTime = re.compile(r'<div class="artTime y">(.*?)</div>')features = ['可爱', '动漫', '手绘', '搞怪']dataList = []for txList in soup.find_all('div', class_='txList'):title = txList.find_all('a')[1].stringdata = []for feature in features:if feature in title:data.append(title)#解析时间html = str(txList)childURL = 'https://www.woyaogexing.com'+''.join(re.findall(findHref, html))child_html = askURL(childURL)childSoup = BeautifulSoup(child_html, 'html.parser')time = re.findall(findTime, str(childSoup))data.append(time)#解析图片链接lazy = childSoup.find_all('img', class_='lazy')imgURL = re.findall(r'src="(.*?)"', str(lazy))data.append(imgURL)# data = data + imgURLdataList.append(data)breakreturn dataList#excel保存
# def saveData(dataList, savePath):
#     wordbook = xlwt.Workbook(encoding='utf-8')
#     wordsheet = wordbook.add_sheet('豆瓣电影Top250', cell_overwrite_ok=True)
#     columns = ['title', 'time', 'imgURL']
#     for i in range(3):
#         wordsheet.write(0, i, columns[i])
#     for i in range(len(dataList)):
#         data = dataList[i]
#         for j in range(len(dataList[0])):
#             wordsheet.write(i+1, j, '\n'.join(data[j]))
#     wordbook.save(savePath)def init_db(dbpath):sql = '''create table headImages(标题 varchar(20),日期 datatime,图片链接 text)'''conn = sqlite3.connect(dbpath)cursor = conn.cursor()cursor.execute(sql)conn.commit()conn.close()#数据库保存
def saveData(dataList, dbpath):init_db(savaDB)conn = sqlite3.connect(dbpath)cur = conn.cursor()for data in dataList:data[0] = "'" + data[0] + "'"data[1] = "'" + '\n'.join(data[1]) + "'"data[2] = "'" + '\n'.join(data[2]) + "'"# data[index] = list(data[index])sql = """insert into headImages(标题,日期,图片链接)values(%s)"""%','.join(data)# print(sql)cur.execute(sql)conn.commit()cur.close()conn.close()if __name__ == '__main__':savePath = r'./头像.xls'savaDB = r'./头像.db'html = askURL(url)dataList = getData(html)# print(dataList)# saveData(dataList, savePath)saveData(dataList, savaDB)

Python爬虫解析(新手快速入门)相关推荐

  1. 通过哪吒动漫豆瓣影评,带你分析python爬虫与BeautifulSoup快速入门

    久旱逢甘霖 西安连着几天温度排行全国三甲,也许是<哪吒之魔童降世>的剧组买通了老天,从踩着风火轮的小朋友首映开始,就全国性的持续高温,还好今天凌晨的一场暴雨,算是将大家从中暑边缘拯救回来了 ...

  2. python多久能上手_小白学习Python,怎样能够快速入门上手

    原标题:小白学习Python,怎样能够快速入门上手 时至今日,Python已经成为最受欢迎的编程语言之一,清晰易读,适用广泛.在TIOBE 排行榜中位居第四,成为名副其实的人工智能第一语言. 那么零基 ...

  3. python编程基础语法-Python编程基础语法快速入门

    1. 课程咨询加老师助理微信:助理1微信: chenjinglei88 ,助理2微信: omf6757 2. 决定购买并想得到陈敬雷老师亲自指导(课程或自己项目难题均可)加老师微信: chenjing ...

  4. pdf python 3.7编程快速入门 潘中强_无python基础,这些书籍可以帮您快速入门。

    利用Python进行数据分析> 定 价:119 元 作者:韦斯·麦金尼(Wes McKinney)著;徐敬一译 ISBN:9787111603702 出 版 社:机械工业出版社 学习Python ...

  5. python爬虫数据提取_入门Python爬虫——提取数据篇

    原标题:入门Python爬虫--提取数据篇 作者: 李菲 来源:人工智能学习圈 前言 在提取数据这一环节,爬虫程序会将我们所需要的数据提取出来.在上一篇文章<入门Python爬虫 -- 解析数据 ...

  6. python编程语法教程-Python编程基础语法快速入门

    1. 课程咨询加老师助理微信:助理1微信: chenjinglei88 ,助理2微信: omf6757 2. 决定购买并想得到陈敬雷老师亲自指导(课程或自己项目难题均可)加老师微信: chenjing ...

  7. 第三章、Ansible常用模块—新手快速入门

    第三章.Ansible常用模块--新手快速入门 文章目录 一. 查看系统上安装的所有模块 二.ansible常用模块 1.常用模块之–USER 2.常用模块之–shell 3.常用模块之–copy 4 ...

  8. 计算机入门新人必学,异世修真人怎么玩?新手快速入门必备技巧

    异世修真人怎么快速入门?最近新出来的一款文字修仙游戏,很多萌新不知道怎么玩?进小编给大家带来了游戏新手快速入门技巧攻略,希望可以帮到大家. 新手快速入门攻略 1.开局出来往下找婆婆,交互给点钱,旁边有 ...

  9. java神奇蜘蛛侠攻略_神奇蜘蛛侠攻略带领新手快速入门

    神奇蜘蛛侠攻略带领新手快速入门,蜘蛛侠是多少人心中的英雄,我们也可以在游戏中当回蜘蛛侠的,这款冒险游戏带你经历一场刺激的旅程,下面就是神奇蜘蛛侠攻略,带领新手们快速的入门. 第一章 教学关,没有什么难 ...

  10. 手把手带你飞Python爬虫+数据清洗新手教程(一)

    本文共有2394字,读完大约需要10分钟. 目录 简介 思考 撸起袖子开始干 1 获取网页源代码 2 在网页源代码里找出所需信息的位置 3 数据清洗 4 完整代码 5 优化后的代码 简介 本文使用An ...

最新文章

  1. 计算机基础知识综合试卷一,计算机基础知识试题及答案a
  2. 一文带你了解java面向对象的三大特性:继承、封装、多态
  3. 把pcl的VTK显示融合到MFC(代码找原作者)
  4. 免费公测中-GPU数据库SQream DB正式上线云市场
  5. 全排列的递归与非递归形式
  6. 收获,不止SQL优化——抓住SQL的本质--第二章
  7. 计算机考研高分扎堆学校如何处理,考研:名校400+扎堆,450+和数学满分频现,网友:这届太厉害了!...
  8. This is the default error page for nginx that is distributed with EPEL.
  9. java 过滤js事件_java中的过滤器与监听器
  10. MATLAB信号处理之常用信号的表示(2)
  11. 手机usb计算机无法连接,手机用USB无法连接电脑怎么办
  12. Python基础函数学习笔记(二)
  13. POJ训练计划3096_Surprising Strings(STL/map)
  14. 软件性能之进程优先级
  15. 【北通游戏手柄安装驱动(WIN10)】
  16. 阿里巴巴战略发展史(转)
  17. JavaScript - 自定义鼠标右键菜单
  18. mysql数据库双机备份_MySQL数据库双机热备份
  19. 若干排序算法简单汇总(一)
  20. win10安装visio2010出错_win10安装office2010时显示错误1907如何解决

热门文章

  1. 小学四年级下册计算机应用,信息技术四年级的下册人教版全册(三小).docx
  2. 开启游戏加速,提高游戏速度
  3. 关于GRANT授权时 “TO附近有语法错误,应为DOUBLECOLON,或ID.” 问题
  4. mAP@0.5与mAP@0.5:0.95的含义,YOLO
  5. 【HTML】HTML作业设计---家具网站设计与开发
  6. android 系统播放器播放https,android:自己实现能播放网络视频url的播放器
  7. 转----没必要参加嵌入式开发培训班
  8. 三级缓存和二级缓存的区别,浅谈Android消息机制原理,面试心得体会
  9. 2021年危险化学品生产单位安全生产管理人员考试及危险化学品生产单位安全生产管理人员考试试题
  10. 转载:一文讲解图像插值算法原理