豆瓣图书Top250共有十页,我们根据之前找出来的规律,利用循环生成这十个网页地址:
for i in range(0, 250, 25):douban_book = 'https://book.douban.com/top250?start=%s' % str(i)12
之后,将它们组装在一起,我们就可以爬取所有图书了:
import requestsfrom bs4 import BeautifulSoupdef spider(url):headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36'}re = requests.get(url, headers=headers)soup = BeautifulSoup(re.text, 'html.parser')items = soup.select('div.pl2 a')for item in items:name = item['title']link = item['href']print(name, link)for i in range(0, 250, 25):douban_book = 'https://book.douban.com/top250?start=%s' % str(i)spider(douban_book)1234567891011121314151617181920
但考虑到输出结果太长,不方便在终端查看,我们可以将爬取到的结果写入文件:
import requestsfrom bs4 import BeautifulSoupdef spider(url, filename):headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36'}re = requests.get(url, headers=headers)soup = BeautifulSoup(re.text, 'html.parser')items = soup.select('div.pl2 a')with open(filename, 'a', encoding=re.encoding) as f:for item in items:line = item['title'] + " " + item['href'] + "n"f.write(line)for i in range(0, 250, 25):douban_book = 'https://book.douban.com/top250?start=%s' % str(i)spider(douban_book, 'doubanTop250.txt')1234567891011121314151617181920
效果:
文章插图
五、防BAN策略爬虫在网页上爬取数据时如果不加任何限制会“高速”访问对方的服务器,如果访问太快容易导致被对方服务器封禁,因为正常人是不会在1秒内访问几十次甚至上百次网站的,这样就会导致我们在一段时间内无法访问这个网站 。所以,如果你访问过于频繁,即使通过修改User-Agent伪装成浏览器,也还是会被识别出爬虫,并限制你的IP访问该网站 。
那么如何防止自己被封禁呢?这里介绍两种策略,一种是降低自己的爬取速度,另一种是IP代理 。
5.1 使用time.sleep()降低爬取速度time.sleep(secs)函数推迟调用线程的运行,可通过参数secs(秒数)来进行设置 。
我们先来看一个例子:
import timefor i in range(0, 10):print(i)time.sleep(1)12345
运行后,终端先是输出0,之后每隔1秒输出一个数字 。倘若不加上time.sleep(1),那么这10个数字会在“一瞬间”打印出来 。显然,time.sleep()延迟了打印这个操作 。利用这个特点,我们可以在之前爬取豆瓣图书Top250的代码中使用time.sleep(),以降低爬取速度,防止被封:
import requestsfrom bs4 import BeautifulSoupfrom time import sleep as pausedef spider(url, filename):headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36'}re = requests.get(url, headers=headers)soup = BeautifulSoup(re.text, 'html.parser')items = soup.select('div.pl2 a')with open(filename, 'a', encoding=re.encoding) as f:for item in items:line = item['title'] + " " + item['href'] + "n"f.write(line)for i in range(0, 250, 25):douban_book = 'https://book.douban.com/top250?start=%s' % str(i)spider(douban_book, 'doubanTop250.txt')pause(1)12345678910111213141516171819202122
这样我们就可以每隔1秒爬取一页,降低了访问频率 。5.2 IP代理除了降低访问频率之外,我们也可以使用代理来解决IP限制的问题 。代理的意思是通过别的IP访问网站 。这样,在IP被封后我们可以换一个IP继续爬取数据,或者每次爬取数据时都换不同的IP,避免同一个IP访问的频率过高,这样就能快速地大规模爬取数据了 。
如何使用代理呢?请看下例:
import requestsproxies = {"http": "http://10.10.1.10:3128","https": "http://10.10.1.10:1080",}requests.get("http://example.org", proxies=proxies)12345678
和headers一样,我们同样需要定义一个字典,但传递的是proxies参数 。我们需要将http和https这两种协议作为键,对应的IP代理作为值,最后将整个字典作为proxies参数传递给requests.get()方法即可 。注:IP代理有免费的和收费的,你可以自行在网上寻找 。在爬取大量数据时我们需要很多的IP用于切换 。因此,我们需要建立一个IP 代理池(字典列表),每次从中随机选择一个传给proxies参数 。
推荐阅读
- Python多线程死锁问题的巧妙解决方法
- 3种方法实现python-matplotlib显示中文
- python第三方库uiautomator2 操作方法汇总
- 不要怕,告别乱如麻的Python报错输出,一行代码就够了
- 每天一个爬虫练习,爬取天气数据,适合新手
- Python 中如何实现参数化测试?
- 快速理解并口、串口、COM口的区别
- Python 为什么没有 void 关键字?
- 快速掌握shell脚本的各种循环语句
- 用Python识别图片中的文字