python学习笔记之网络爬虫(八) 静态网页和动态网页爬取(1)静态网页爬取

T Xiao Ang Zai 11月26号

版本:python3.7

编程软件:sublime

 

爬取信息是一个很大的需求,小到单个页面,某个站点,大到搜索引擎(百度、谷歌)的全网抓取。只要人能看到的东西,理论上都是爬虫可以获取的。不论静态页面还是动态页面。也不论pc端的页面还是移动端的app。爬虫,有很多语言可选,python、php、go、java···甚至是c。但现在的主流是python作为爬虫的编程语言,因为它简单易上手,并且效率高且节约时间。

而爬取网页信息有很多python库,urllib,urllib2(python3 已不用),requests。下面先比较它们的不同之处:

urllib和urllib2是python标准库,就是大家安装了python,这两个库就已经可以直接使用了;requests是第三方库,不是python基金会实现的,但是功能是很强大的。

但urllib和urllib2都是通过url打开资源,其中urllib只能接受url,却如法对请求进行headers的伪装,这样写的爬虫发送的请求会被很多网站直接阻挡掉,伪装性不好,需要很复杂的修改,这在前面的文章中已经介绍过了。

而requests库可以实现urllib和urllib2的所有功能,而且还有它们没有的优势,在使用过程中,requests比较更好用。

 

一:什么是静态网页和动态网页?

1.静态网页:通俗来讲,只有HTML格式的网页通常被称为静态网页。这些网页的数据比较容易获取,由于所有的数据都显示在网页的HTML代码中。在用python抓取的过程中,有一个强大的Request库能够轻易地发送HTTP请求,供我们进行爬取静态网页。

2.动态网页:不只有HTML代码写出的网页被称为动态网页,这些网页一般由CSS,JavaScript代码和HTML代码一起构成网页,它们用Ajax动态加载网页的数据不一定出现在HTML代码中,这就需要复杂的操作。

 

二:静态网页爬取

1.Request安装和简单操作

(1)安装

在cmd或terminal中写入

pip install requests

即可。

(2)获取网页内容‘

Request最常用的功能是获取某网页的内容,我们先获取前面的博客的内容:

import requests

rr = requests.get('https://blog.csdn.net/ITxiaoangzai/article/details/83904139')
print("文本编码为:",rr.encoding)
print("响应状态码为:",rr.status_code)
print("内容字符串为:",rr.text)

这样就返回了一个名为rr的response响应对象,我们可以调用相应的函数获取需要的信息。结果如下图所示:
python学习笔记之网络爬虫(八) 静态网页和动态网页爬取(1)静态网页爬取_第1张图片

...

python学习笔记之网络爬虫(八) 静态网页和动态网页爬取(1)静态网页爬取_第2张图片

下面是一些基本的方法:

print(response.status_code)  # 打印状态码,200表示请求成功;4xx表示客户端错误;5xx表示服务器错误响应
int(response.url)          # 打印请求url
print(response.headers)      # 打印头信息
print(response.cookies)      # 打印cookie信息
print(response.text)  #以文本形式打印网页源码
print(response.content) #以字节流形式打印

还可以用response.json()是Response中内置的JSON解码器。

 

2.定制Requests

现在我们可以爬取网页的html代码数据了,但有时候我们只需要一部分数据,那就需要对Requests的参数进行设置才能获取我们需要的数据,包括传递URL参数,定制请求头,发送POST请求,设置超时等。

下面对这些操作进行讲解:

(1)传递URL参数

为了请求特定的数据,我们需要在URL的查询字符串中加入一些特定数据。这些数据一般会跟在一个问号后面,并且以键值对的形式放在URL中。

在Request中,我们可以直接把这些参数保存在字典中,用params构建到URL中。

下面是一个实例:

import requests

key_dict = {'one':'value1','two':'value2'}
rr = requests.get('https://blog.csdn.net/ITxiaoangzai/article/details/83904139',params = key_dict)
print("URL正确编码为:",rr.url)
print("字符串方式的响应的内容是:",rr.text)

我们看下结果:

python学习笔记之网络爬虫(八) 静态网页和动态网页爬取(1)静态网页爬取_第3张图片

(2) 定制请求头

    请求头Headers提供了关于请求,响应或其他发送实体的消息,如果没有定制请求头或请求的请求头和实际网页不一致,就可能无法返回正确结果。Requests不会基于定制的请求头Headers而改变自己的行为,只有在最后的请求中,请求头的信息才会被传递进去。

我们可以根据下面的方法找到正确的请求头:

打开之前博客的内容:

python学习笔记之网络爬虫(八) 静态网页和动态网页爬取(1)静态网页爬取_第4张图片

然后我们单击右键,选择检查(有的浏览器也叫审查元素),然后选Network选项:

我们选择python的图片,就会发现在左侧的资源栏中拦截到了一个文件,那就是图片文件,我们在Header中可以看到Request Headers的详细信息(其实在之前的博客中已经介绍过了),这里只需要提取出请求头中重要的部分,也就是user-agent的部分:

然后我们在requests.get()函数中加入我们定制的请求头:

import requests

headers = {
	'user-agent' : 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.26 Safari/537.36 Core/1.63.5702.400 QQBrowser/10.2.1893.400',
	'Host' : 'https://img-blog.csdn.net/20180716181513532?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0lUeGlhb2FuZ3phaQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70'
}

r = requests.get('https://blog.csdn.net/ITxiaoangzai/article/details/83904139',headers = headers)
print("字符串方式的响应的内容是:",r.text)
print("响应码为:",r.status_code)

结果如下:
python学习笔记之网络爬虫(八) 静态网页和动态网页爬取(1)静态网页爬取_第5张图片

python学习笔记之网络爬虫(八) 静态网页和动态网页爬取(1)静态网页爬取_第6张图片

这里返回的响应码为400说明我们的代码是错误的。这说明我们并不能用这种方法爬取图片。关于如何正确地爬取图片,在之后的文章中会给大家讲到。

 

3.发送POST请求

除了GET请求外,有时还需要发送一些编码为表单形式的数据,这时只需要传递一个字典给Request中的data参数,这些数据字典就会在发送请求时自动编码为表单形式。在之前的爬取有道词典的文章中我们就用到了该请求。

 

4.超时

可以用Requests在timeout参数设定如果规定时间内没有响应,就抛出异常。

 

 三:实例爬取豆瓣前100个电影的片名

先打开网址https://www.douban.com/doulist/36513321/

然后我们找到每个影片的HTML代码:

python学习笔记之网络爬虫(八) 静态网页和动态网页爬取(1)静态网页爬取_第7张图片

 

在这里,我们需要的信息均在

import requests from bs4 import BeautifulSoup def getUrl(): url = "https://www.douban.com/doulist/36513321/" headers = { 'user-agent' : 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.26 Safari/537.36 Core/1.63.5702.400 QQBrowser/10.2.1893.400', } list = [] r = requests.get(url,headers = headers) soup = BeautifulSoup(r.text,"lxml") thisUrl = soup.find_all('div',class_ = "title") for each in thisUrl: everyUrl = each.text.strip() list.append(everyUrl) print(list) print("响应码为:",r.status_code) def main(): getUrl() if __name__ == '__main__': main()

这是我们会发现一个错误:

python学习笔记之网络爬虫(八) 静态网页和动态网页爬取(1)静态网页爬取_第8张图片

这里把lxml改为html.parse即可:

import requests
from bs4 import BeautifulSoup

def getUrl():
	url = "https://www.douban.com/doulist/36513321/"
	headers = {
		'user-agent' : 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.26 Safari/537.36 Core/1.63.5702.400 QQBrowser/10.2.1893.400',
	}

	list = []
	r = requests.get(url,headers = headers)
	soup = BeautifulSoup(r.text,"html.parser")
	thisUrl = soup.find_all('div',class_ = "title")
	for each in thisUrl:
		everyUrl = each.text.strip()
		list.append(everyUrl)
	print(list)
	print("响应码为:",r.status_code)

def main():
	getUrl()

if __name__ == '__main__':
	main()

结果如下:


这里要爬取的是100个剧名,这里我们得到的是只有25个,要爬取所有的要分析一下网址url:

https://www.douban.com/doulist/36513321/?start=0&sort=seq&playable=0&sub_type=

https://www.douban.com/doulist/36513321/?start=25&sort=seq&playable=0&sub_type=

发现只有start=" "后面的不同,我们可以分析四次,或者利用一个循环来进行:

import requests
from bs4 import BeautifulSoup

def getUrl():
	headers = {
		'user-agent' : 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.26 Safari/537.36 Core/1.63.5702.400 QQBrowser/10.2.1893.400',
	}
	for i in range(0,4):
		url = "https://www.douban.com/doulist/36513321/?start={}&sort=seq&playable=0&sub_type=".format(i*25)
		list = []
		r = requests.get(url,headers = headers)
		soup = BeautifulSoup(r.text,"html.parser")
		thisUrl = soup.find_all('div',class_ = "title")
		for each in thisUrl:
			everyUrl = each.text.strip()
			list.append(everyUrl)
		print(list)
		print("响应码为:",r.status_code)

def main():
	getUrl()

if __name__ == '__main__':
	main()

在这里我们用format()来格式化字符串(这里也可以用%来格式化字符串),我们看下结果:

python学习笔记之网络爬虫(八) 静态网页和动态网页爬取(1)静态网页爬取_第9张图片

这里看到我们已经成功爬取我们想要的内容了。

 

欢迎大家对我的学习笔记提出宝贵的意见,有意者可以加我的qq:1657264184和我一起进行讨论。

你可能感兴趣的:(share,python,sublime)