爬虫笔记
模拟发送 HTTP 请求
GET请求
GET请求是HTTP协议中定义的一种请求方法,用于从服务器获取数据。当发起一个GET请求时,客户端(通常是用户的网页浏览器)向服务器发送一个请求,请求服务器返回指定的资源或数据。当我们用浏览器打开网页时,其实发送的最原始的请求就是 GET 请求
1 | import requests |
可以看到,我们得到的是一个 Response
对象
如果我们要获取网站返回的数据,可以使用 text
或者 content
属性来获取
text
:是以字符串的形式返回数据
content
:是以二进制的方式返回数据
POST请求
POST请求是HTTP协议中定义的另一种请求方法,用于向服务器提交数据。当发起一个POST请求时,客户端向服务器发送数据,并且这些数据通常作为HTTP请求的一部分(称为请求体)被发送。
对于 POST 请求,一般就是提交一个表单。data
当中,就是需要传递的表单信息,是一个字典类型的数据。
1 | r = requests.post('http://www.xxxx.com', data={"key": "value"}) |
header 增强
requests 发送的请求所带的请求头中 User-Agent 会标识为 python 程序发送的请求。
由于这种行为仅仅是消耗服务器资源带来成本,但是不会给对方带来任何好处(搜索引擎的爬虫除外),所以有一些网站会加入反爬机制,通过识别 headers 来拒绝对你的请求进行响应。
所以需要做一些 header 增强。比如:UA,Cookie,host 等等信息。
浏览器访问网站时的 headers 可以在httpbin.org/headers 中得到。
1 | { |
将上面的请求头复制下来,传给 requests.get()
函数,即可将请求伪装成浏览器。
requests.get()
的语法是:requests.get(url,kwargs)
。
其中,url 是我们想要访问的链接,kwargs 是可选参数,包括params、data、json、headers、cookies、auth、files、timeout、proxies、stream、verify、cert等。常用的参数有data、headers。
1 | import requests |
解析 HTML
现在我们已经获取到了网页返回的数据,即 HTML 代码,下面就需要解析 HTML,来提取其中有效的信息。
BeautifulSoup
BeautifulSoup
是 Python 的一个库,最主要的功能是从网页解析数据。
1 | from bs4 import BeautifulSoup # 导入 BeautifulSoup 的方法 |
bs4
是BeautifulSoup
库的简称,它是一个用于解析 HTML 和 XML 文档的 Python 库,通常用于网页抓取和数据分析。BeautifulSoup
能够处理复杂的 HTML 网页内容,并提供简单易用的 API 来访问和修改数据。
BeautifulSoup
库的名字来源于一个儿童故事中的角色,这个角色喜欢“把字符串咀嚼成美味的网络抓取汤”,因此得名“BeautifulSoup”。
BeautifulSoup 的一些简单用法
1 | print(soup.title) # 获取文档的 title |
在HTML和XML文档中,p
结点通常指的是 <p>
标签创建的元素,它代表一个段落(Paragraph)。<p>
标签是块级元素,用于定义文本的一个段落。在网页中,浏览器会在段落之间添加一些垂直的空白,以区分不同的段落。
例如:
1 | <p>这是一个段落。</p> |
在上面的HTML代码中,每个 <p>
元素都定义了一个文本段落。
同样,a
结点指的是 <a>
标签创建的元素,它代表一个锚点(Anchor)。<a>
标签用于创建超链接,允许用户通过点击跳转到其他网页、文件、位置或其他资源。<a>
标签可以包含文本、图片等任何内容,并且通常有一个 href
属性,指定了链接的目标URL。
例如:
1 | <a href="https://www.example.com">访问示例网站</a> |
在上面的HTML代码中,<a>
元素创建了一个文本为“访问示例网站”的超链接,当用户点击这个链接时,浏览器会跳转到 https://www.example.com
这个URL。
find_all
在Python的BeautifulSoup
库中,find_all
方法用于搜索HTML或XML文档,并返回所有匹配指定条件的元素。find_all
方法可以接受多种参数,包括要查找的标签名、属性、CSS类等。
1 | data = content.find_all('div', attrs={'class': 'cover'}) |
这行代码的作用是:
content
是一个BeautifulSoup
对象,它代表了已经解析的HTML文档。find_all
方法被调用,第一个参数'div'
指定了要搜索的标签名,即<div>
。attrs={'class': 'cover'}
参数指定了要搜索的<div>
标签必须具有class
属性,且属性值包含cover
。这意味着find_all
方法将返回所有类名为cover
的<div>
元素。
结果 data
将是一个列表,包含了文档中所有匹配的 <div>
元素。每个元素都是一个 Tag
对象,你可以对这些对象进行进一步的操作,例如提取文本、属性或其他嵌套的标签。
例如,如果您想要遍历这些 <div>
元素并打印它们的文本内容,可以这样做:
1 | for div in data: |
这将会打印出每个类名为 cover
的 <div>
元素中的文本内容。
<div>
元素是HTML文档中的一个块级元素,它用于定义文档中的一个区域或部分,并且可以用来组合其他HTML元素。<div>
是 “division” 的缩写,意为“分区”。
find
在 BeautifulSoup
中,find
方法用于搜索当前元素下的子元素,并返回第一个匹配的元素。如果找到了多个匹配的元素,find
方法只返回第一个匹配的元素。如果没有找到匹配的元素,则返回 None
。
例如,假设我们有以下HTML代码片段:
1 | <div class="cover"> |
如果我们已经有一个 BeautifulSoup
对象 d
,它代表上面的 <div>
元素,那么我们可以使用 d.find('img')
来找到第一个 <img>
子元素。
我们可以进一步从 img_tag
中获取 src
属性,得到图片的URL:
1 | img_url = img_tag['src'] |
在这里,img_url
的值将是 "image1.jpg"
。
get_text
在 BeautifulSoup
中,get_text()
方法是一个用于提取标签内文本内容的方法。它将返回一个字符串,该字符串包含指定标签及其所有子标签的文本内容,而不包含任何HTML标签或属性。
get_text()
方法可以用于任何 Tag
对象,它会递归地提取所有子标签的文本,并将它们连接成一个字符串。
这里有一些 get_text()
方法的基本用法:
1 | from bs4 import BeautifulSoup |
输出将会是:1
2
3Page Title
这是一个段落。
这是一个链接
你也可以在特定的标签上调用 get_text()
方法来提取该标签及其子标签的文本:1
2
3# 获取特定标签 <div> 的文本内容
div_text = soup.div.get_text()
print(div_text)
输出将会是:1
2这是一个段落。
这是一个链接get_text()
方法还有一些参数,可以用来控制如何提取文本:
strip
: 布尔值,默认为False
,表示是否去除文本前后的空白字符。separator
: 字符串,用于连接各个文本片段的分隔符,默认为 “”,表示不添加分隔符。
下载图片
1 | def download_picture(pic_l): |
if not os.path.exists(r'picture'):
- 这个条件判断语句检查在当前目录下是否存在一个名为
picture
的文件夹。os.path.exists
是一个检查路径是否存在的函数,r'picture'
表示picture
文件夹的路径,r
前缀表示这是一个原始字符串,不处理反斜杠\
作为转义字符。
- 这个条件判断语句检查在当前目录下是否存在一个名为
os.mkdir(r'picture')
- 如果上述条件成立(即
picture
文件夹不存在),这行代码会创建一个名为picture
的新文件夹。
- 如果上述条件成立(即
pic = requests.get(i)
- 在循环内部,这行代码使用
requests.get
函数从互联网上获取(下载)URLi
指向的图片内容,并将响应内容赋值给变量pic
。
- 在循环内部,这行代码使用
p_name = i.split('/')[7]
- 这行代码将URL
i
按照斜杠/
分割成多个部分,并取出第8个部分(列表索引为7)作为图片的文件名。这里假设URL的第八部分是图片的文件名。
- 这行代码将URL
with open('picture\\' + p_name, 'wb') as f:
- 这行代码打开一个文件,文件路径是
picture
文件夹加上图片的文件名p_name
,文件以二进制写模式(‘wb’)打开。with
语句确保文件使用后会被正确关闭。变量f
是打开文件的引用。
- 这行代码打开一个文件,文件路径是
f.write(pic.content)
- 最后,这行代码将下载的图片内容
pic.content
写入到文件f
中,完成图片的保存。
- 最后,这行代码将下载的图片内容