要使用Python 抓取网页,首先我们要学习下面四个模块:

作用
webbrowser 打开浏览器获取指定页面;
requests 从因特网下载文件和网页;
Beautiful Soup 解析HTML,即网页编码的格式;
selenium 启动并控制一个Web 浏览器,能够填写表单,并模拟鼠标点击。

小项目:利用webbrowser 模块的bilibiliSearch.py

webbrowser 模块的open()函数可以启动一个新浏览器,打开指定的URL。

import webbrowser
webbrowser.open("https://bilibili.com")

例如运行上面的这段代码,系统就会启动一个新的标签页,打开B站了。但是,这也是webbrowser 模块唯一能做的事了。

假如我们要实现一个功能:使用Bilibili 搜索指定或剪贴板中的文字。那我们的程序需要做到:

  • 从命令行参数或剪贴板中取得要搜索的内容;
  • 打开Web 浏览器,指向搜索结果。

弄清指定地点的Bilibili Search Url 地址

我们首先在B站手动搜索“孙笑川 鬼畜”,可以发现地址栏的Url 网址为:“https://search.bilibili.com/all?keyword=孙笑川%20鬼畜”,于是我们可以发现,只要将要搜索的内容放在keyword= 后即可,多个关键字用空格分开,在网址中为20%表示。

处理命令行参数

为了从命令行参数中导入要搜索的内容,我们需要导入sys 包,并使用sys.argv来取得其内容。

处理剪贴板内容

使用pyperclip 包中的pyperclip.paste()函数来取得剪贴板中的内容。

于是,整个程序的代码如下:

import webbrowser, sys, pyperclip

if len(sys.argv) > 1:
# Get address from command line.
address = ' '.join(sys.argv[1:])
else:
# Get address from clipboard.
address = pyperclip.paste() webbrowser.open("https://search.bilibili.com/all?keyword="+address)

用requests 模块从Web 下载文件

requests.get()函数接收一个要下载的Url 地址字符串,返回一个Response 对象,其中包含了Web 服务器对你的请求做出的响应。

>>> import requests
>>> res = requests.get('http://www.gutenberg.org/cache/epub/1112/pg1112.txt')
>>> type(res)
<class 'requests.models.Response'>
>>> res.status_code == requests.codes.ok
True
>>> len(res.text)
179378
>>> requests.codes.ok
200
>>> print(res.text[:300])
The Project Gutenberg EBook of Romeo and Juliet, by William Shakespeare *******************************************************************
THIS EBOOK WAS ONE OF PROJECT GUTENBERG'S EARLY FILES PRODUCED AT A
TIME WHEN PROOFING METHODS AND TOOLS WERE NOT WELL DEVELOPED. THERE
IS AN IMPROVED

该对象包含若干属性,status_code称为状态码,该属性值可以查看这次请求是否成功,text属性中则包括了该网页中的文本信息。值得一提的是,访问成功的状态码为200,一般来说,其他均为失败。

我们可以在访问失败时使用raise_for_status()方法抛出异常,使程序停止。如果我们只希望抛出异常,不希望程序停止,则可以使用tryexcept包裹该语句。

>>> res = requests.get("http://www.donotexists777.com")
>>> res.status_code
404
>>> res.raise_for_status()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "D:\Anaconda3\envs\mlbook\lib\site-packages\requests\models.py", line 940, in raise_for_status
raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 404 Client Error: Not Found for url: http://miwifi.com/diagnosis/index.html

将下载的文件保存至硬盘

>>> import requests
>>> res = requests.get('http://www.gutenberg.org/cache/epub/1112/pg1112.txt')
>>> res.raise_for_status()
>>> playFile = open('RomeoAndJuliet.txt', 'wb')
>>> for chunk in res.iter_content(100000):
... playFile.write(chunk)
...
100000
79380
>>> playFile.close()

使用标准的open()write()方法即可保存Web 页面至本地文件中,在这里使用wb 参数视为了以二进制的方式打开文件,并且使我们能够写入该文本中的“Unicode编码”。

为了减少内存的使用量,我们使用iter_content()方法分批次将文本写入本地文档。

使用BeautifulSoup 模块解析HTML

不使用政策表达式解析Html 格式的原因在于,Html 的格式可以有许多不同的方式,并且仍然被认为是有效的Html ,但尝试用正则表达式来捕捉所有这些可能的变化,将非常繁琐,并且容易出错。BeautifulSoup 模块则不容易导致缺陷。

从HTML 创建一个BeautifSoup 对象

bs4.BeautifulSoup() 函数调用时需要一个字符串,其中包含将要解析的HTML。bs4.BeautifulSoup() 函数返回一个BeautifulSoup 对象。

>>> import requests, bs4
>>> res = requests.get('http://www.baidu.com')
>>> res.raise_for_status()
>>> baiduSoup = bs4.BeautifulSoup(res.text)
>>> type(baiduSoup)
<class 'bs4.BeautifulSoup'>

使用select() 方法寻找元素

针对要寻找的元素,调用select()方法,传入一个字符串作为CSS“选择器”,这样就可以取得Web 页面元素。

<!-- This is the example.html example file. -->

<html><head><title>The Website Title</title></head>
<body>
<p>Download my <strong>Python</strong> book from <a href="http://
inventwithpython.com">my website</a>.</p>
<p class="slogan">Learn Python the easy way!</p>
<p>By <span id="author">Al Sweigart</span></p>
</body></html>

来看上面的一个例子,将上面这段代码保存为“example.html”,并保存在当前文件夹下。

>>> from bs4 import BeautifulSoup
>>> exampleFile = open('./example.html')
>>> exampleSoup = BeautifulSoup(exampleFile.read(), features='html.parser')
>>> elems = exampleSoup.select('#author')
>>> type(elems)
<class 'list'>
>>> len(elems)
1
>>> type(elems[0])
<class 'bs4.element.Tag'>
>>> elems[0].getText()
'Al Sweigart'
>>> str(elems[0])
'<span id="author">Al Sweigart</span>'
>>> elems[0].attrs
{'id': 'author'}

小项目

爬个动漫排行- -

为了某些需要登陆才能查看到的番我们需要先关闭所有浏览器,然后在cmd输入:

"C:\Program Files (x86)\Microsoft\Edge Beta\Application\msedge.exe" --remote-debugging-port=8888

接下来:

from selenium import webdriver
import time
"""
First, run:
"C:\Program Files (x86)\Microsoft\Edge Beta\Application\msedge.exe" --remote-debugging-port=8888
in the cmd.
"""
options = webdriver.ChromeOptions()
options.debugger_address = "127.0.0.1:" + '8888'
options.binary_location = r"C:\Program Files (x86)\Microsoft\Edge Beta\Application\msedge.exe"
chrome_driver_binary = r"D:\APP\MicrosoftWebDriver.exe"
driver = webdriver.Chrome(chrome_driver_binary, chrome_options=options)
for i in range(1, 100):
url = "https://bangumi.tv/anime/tag/%E6%90%9E%E7%AC%91?page=" + str(i)
driver.get(url)
time.sleep(5) # Let the user actually see something!
filepath = str(i) + '.html'
with open(filepath, 'wb') as f:
f.write(driver.page_source.encode("utf-8", "ignore"))
print(filepath + "写入成功!")
f.close()

上面的是用来把网页文件下载到本地的0 0

下面的用来解析的- -

from bs4 import BeautifulSoup
import re dateRegex = re.compile(r"(\d{4})\D+(\d{1,2})\D+(\d{1,2})") # 规范化日期
with open('topAnime.txt', 'a', encoding="utf-8") as f:
for i in range(1, 77):
filepath = str(i) + '.html'
soup = BeautifulSoup(open(filepath, encoding="utf-8"), 'html.parser')
nameList = soup.find_all(name="h3")
for name in nameList:
link = "https://bangumi.tv" + name.contents[1]["href"]
f.writelines('[' + name.contents[1].string.strip('\n') + ']' + '(' + link + ')')
if len(name) >= 4:
f.writelines("\t" + name.contents[3].string.strip('\n'))
else:
f.writelines("\tNone")
for sibling in name.next_siblings:
try:
if sibling.attrs["class"] == ['info', 'tip']:
# f.writelines("\tinfo: " + sibling.string.strip())
date = dateRegex.search(sibling.string.strip())
try:
f.writelines("\t" + date[1] + '-' + date[2] + '-' + date[3])
except TypeError:
continue
if sibling.attrs["class"] == ['rateInfo']:
try:
f.writelines("\t" + sibling.contents[3].string.strip('\n'))
except IndexError:
f.writelines("\t0")
continue
except AttributeError:
continue
f.writelines("\n")
f.close()
# timeList = soup.find_all(attrs={"class": "info tip"})
# for time in timeList:
# f.writelines(time.string)

最终的结果这里就不展示了- -

[Python学习笔记]爬虫的更多相关文章

  1. python学习笔记——爬虫学习中的重要库urllib

    1 urllib概述 1.1 urllib库中的模块类型 urllib是python内置的http请求库 其提供了如下功能: (1)error 异常处理模块 (2)parse url解析模块 (3)r ...

  2. python学习笔记——爬虫中提取网页中的信息

    1 数据类型 网页中的数据类型可分为结构化数据.半结构化数据.非结构化数据三种 1.1 结构化数据 常见的是MySQL,表现为二维形式的数据 1.2 半结构化数据 是结构化数据的一种形式,并不符合关系 ...

  3. python学习笔记——爬虫的抓取策略

    1 深度优先算法 2 广度/宽度优先策略 3 完全二叉树遍历结果 深度优先遍历的结果:[1, 3, 5, 7, 9, 4, 12, 11, 2, 6, 14, 13, 8, 10] 广度优先遍历的结果 ...

  4. python学习笔记目录

    人生苦短,我学python学习笔记目录: week1 python入门week2 python基础week3 python进阶week4 python模块week5 python高阶week6 数据结 ...

  5. Python学习笔记之基础篇(-)python介绍与安装

    Python学习笔记之基础篇(-)初识python Python的理念:崇尚优美.清晰.简单,是一个优秀并广泛使用的语言. python的历史: 1989年,为了打发圣诞节假期,作者Guido开始写P ...

  6. python学习笔记1之-python简介及其环境安装

    python学习笔记之-python简介及其环境安装 最近几年python之火不用多说,最近开始利用时间自学python,在学习的过程中,按照自己的思路和理解记录下学习的过程,并分享出来,如果正好你也 ...

  7. python学习笔记整理——字典

    python学习笔记整理 数据结构--字典 无序的 {键:值} 对集合 用于查询的方法 len(d) Return the number of items in the dictionary d. 返 ...

  8. VS2013中Python学习笔记[Django Web的第一个网页]

    前言 前面我简单介绍了Python的Hello World.看到有人问我搞搞Python的Web,一时兴起,就来试试看. 第一篇 VS2013中Python学习笔记[环境搭建] 简单介绍Python环 ...

  9. python学习笔记之module && package

    个人总结: import module,module就是文件名,导入那个python文件 import package,package就是一个文件夹,导入的文件夹下有一个__init__.py的文件, ...

随机推荐

  1. java调用shell脚本执行操作

    //定时清空 日志 String shellString = "sh /home/jyapp/delete_log.sh"; Process process = Runtime.g ...

  2. 2019牛客多校 Round3

    Solved:3 Rank:105 治哥出题了 我感动哭了 A Graph Game (分块) 题意:1e5个点 2e5条边 s(x)表示与x点直接相邻的点集合 有两种操作 1种将按输入顺序的边第l条 ...

  3. Codeforces Round #608 (Div. 2) E. Common Number (二分,构造)

    题意:对于一个数\(x\),有函数\(f(x)\),如果它是偶数,则\(x/=2\),否则\(x-=1\),不断重复这个过程,直到\(x-1\),我们记\(x\)到\(1\)的这个过程为\(path( ...

  4. zoj3545Rescue the Rabbit (AC自动机+状压dp+滚动数组)

    Time Limit: 10 Seconds      Memory Limit: 65536 KB Dr. X is a biologist, who likes rabbits very much ...

  5. 洛谷 P2880 [USACO07JAN]Balanced Lineup G (ST表模板)

    题意:给你一组数,询问\(q\)次,问所给区间内的最大值和最小值的差. 题解:经典RMQ问题,用st表维护两个数组分别记录最大值和最小值然后直接查询输出就好了 代码: int n,q; int a[N ...

  6. Link/Cut Tree CodeForces - 614A 暴力+爆 long long 处理

    题意: 给你一个区间[l,r],让你从小到大输出k^x,设y=k^x,要保证y在区间[l,r]中 题解: 就算k是最小的2也不需要枚举多少次就到long long的极限了,所以暴力没商量,根本不会TL ...

  7. Codeforces Round #669 (Div. 2) C. Chocolate Bunny (交互,构造)

    题意:有一个长度为\(n\)的隐藏序列,你最多可以询问\(2n\)次,每次可以询问\(i\)和\(j\)位置上\(p[i]\ mod\ p[j]\)的结果,询问的格式是\(?\ x\ y\),如果已经 ...

  8. python代理池的构建3——爬取代理ip

    上篇博客地址:python代理池的构建2--代理ip是否可用的处理和检查 一.基础爬虫模块(Base_spider.py) #-*-coding:utf-8-*- ''' 目标: 实现可以指定不同UR ...

  9. WPF 无法对元素“TextBox”设置 Name 特性值“TB2”

    错误信息 无法对元素"TextBox"设置 Name 特性值"TB2"."TextBox"在元素"UserControl1&quo ...

  10. nginx+lua实现灰度发布/waf防火墙

    nginx+lua 实现灰度发布 waf防火墙 课程链接:[课程]Nginx 与 Lua 实现灰度发布与 WAF 防火墙(完)_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili 参考博客 Nginx ...