爬虫python第二页_Python爬虫二:静态网页爬虫

本文介绍了Python爬虫的基础,包括使用BeautifulSoup解析和提取网页数据,以及如何应对网站的反爬虫策略。通过实例讲解了如何使用BeautifulSoup的find()和find_all()方法,结合CSS选择器定位所需信息。同时,文章讨论了爬取整个网站的方法,如何处理IP限制和理解并遵守robots.txt规则。
摘要由CSDN通过智能技术生成

1. BeautifulSoup

处理数据分为两步:解析数据和提取数据。处理数据需要用到一个第三方库:BeautifulSoup,可以通过在命令行中输入pip install beautifulsoup4来进行安装。

1) 解析数据

以豆瓣读书Top250为例,将其网页源代码解析为BeautifulSoup对象:

import requests

from bs4 import BeautifulSoup

headers = {

'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36'

}

res = requests.get('https://book.douban.com/top250', headers = headers)

soup = BeautifulSoup(res.text, 'html.parser')

Note: 添加headers参数是为了应对反爬虫机制。

创建BeautifulSoup对象时需要传入两个参数,第一个参数是要解析的HTML文本,第二个参数是解析HTML的解析器,html.parser是Python中内置的解析器。

BeautifulSoup对象打印出来虽与网页源代码一样,但它有许多强大的方法和属性,可以方便快捷地提取出需要的数据。

2) 提取数据

BeautifulSoup对象里的find()和find_all()是提取数据最常用的两个方法。find():返回符合条件的首个数据

find_all():返回符合条件的所有数据

它们的用法是传入HTML标签名称,返回符合该HTML标签的数据。除此之外,他们还支持传入HTML属性进行筛选,返回符合条件的数据。例如:

# 查找id='doubanapp-tip'的div标签

soup.find('div', id='doubanapp-tip')

# 查找所有class='rating_nums'的span标签

soup.find_all('span', class_='rating_nums')

通过id、class等HTML属性的筛选,可以快速准确地找到需要的数据。当一个条件无法精确定位时,也可以传入多个HTML属性进行筛选,返回同时符合这些条件的数据。

3) Tag对象

BeautifulSoup将HTML中的元素封装成了Tag对象。和BeautifulSoup对象一样,Tag对象也有find()和find_all()方法。因此,可以通过不断调用这两个方法,一层一层地找到需要的数据。

# 找到所有class='item'的div标签

items = soup.find_all('div', class_='item')

for i in items:

# 找到class_='item'的div标签中的a标签

print(i.find('a'))

这样,就找到了所有书名的数据。但此时返回的还是Tag对象,如果只想要书名和对应的链接,则可以用Tag对象的text属性和HTML属性名取值。

items = soup.find_all('div', class_='item')

for i in items:

tag = i.find('a')

# 获取text属性

name = tag.text

# 获取href属性值

link = tag['href']

print(name, link)

Tag对象常用的属性和方法:tag.find():返回符合条件的首个数据

tag.find_all():返回符合条件的所有数据

tag.text:获取标签的文本内容

tag['属性名']:获取标签HTML属性的值

4) CSS选择器

在CSS选择器中,#代表id,.代表class,比如:#login表示id='login'的所有元素,.item表示class='item'的所有元素。也可以和标签名组合在一起,比如:a#login表示所有id='login'的a元素,p.item表示所有class='item'的p元素,#login.item表示所有id='login'且class='item'的元素,.item.book表示所有class同时为item和book的元素。

子元素选择:当两个选择器之间加了空格,如:.item .book,表示选择所有嵌套在class='item'的元素里面class='book'的元素。如果只需要直接嵌套在第一层符合条件的元素,可以用>分隔,比如:.item > .book。

BeautifulSoup对象中有一个select()方法,将CSS选择器传进去可以直接找到所需的元素,比如上一部分的代码可以简化为:

items = soup.select('div.item a')

for i in items:

name = i.text

link = i['href']

print(name, link)

2. 爬虫进阶

1) 爬取整个网站

前面介绍的方法只能爬取一个页面的数据,为了爬取整个网站,首先要观察网址的查询字符串。以豆瓣读书为例,点击第二页后,网址变成了https://book.douban.com/top250?start=25,?start=25这一部分就是查询字符串,其格式是?key1=value1&key2=value2。查询字符串作为用于搜索的参数或处理的数据传送给服务器处理。

url = 'https://book.douban.com/top250?start={}'

urls = [url.format(num * 25) for num in range(10)]

print(urls)

通过观察每一页网址的规律,可以推测出start的计算公式,用如上代码即可自动生成所有数据的地址。

获取所有页面的地址后,将一个页面的爬虫代码封装成函数,唯一会变的网页地址作为参数,再用for循环遍历所有的网页地址,依次传入封装好的函数,即可实现整个网站的爬取。

import requests

import time

from bs4 import BeautifulSoup

def get_douban_books(url):

headers = {

'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36'

}

res = requests.get(url, headers=headers)

soup = BeautifulSoup(res.text, 'html.parser')

items = soup.find_all('div', class_='pl2')

for i in items:

tag = i.find('a')

name = tag['title']

link = tag['href']

print(name, link)

url = 'https://book.douban.com/top250?start={}'

urls = [url.format(num * 25) for num in range(10)]

for item in urls:

get_douban_books(item)

# 暂停1秒防止访问太快被封

time.sleep(1)

2) 反爬虫

反爬虫是网站限制爬虫的一种策略,让爬虫在网站可接受的范围内爬取数据,不至于导致网站瘫痪无法运行。

①判别身份

有些网站在识别出爬虫后,会拒绝爬虫的访问,如果用爬虫直接爬取它,则输出结果为空。这是由于服务器会通过请求头(requests headers)里的信息来判别访问者的身份。

查看网站请求头的方法:在开发者工具中点击Network标签

点击第一个请求

找到Request Headers

找到user-agent字段

为了将爬虫伪装成浏览器,避免被服务器识别出来,需要在requests中定制请求头:定义一个字典,请求头字段作为键,字段内容作为值,传递给headers参数。大部分情况下,只需添加user-agent字段即可。

②IP限制

当爬取大量数据时,由于访问过于频繁,可能会被限制IP。因此,常使用time.sleep()来降低访问的频率。

此外,也可以使用代理来解决IP限制的问题,以便快速地大规模爬取数据。和headers一样,定义一个字典,将http和https这两种协议作为键,对应的IP代理作为值,最后将整个字典作为proxies参数传递给requests.get()方法。

爬取大量数据时需要很多的IP进行切换,因此,需要建立一个IP代理池(列表),每次从中随机选择一个传给proxies参数:

# IP代理池

proxies_list = [

{

"http": "……",

"https": "……"

},

{

"http": "……",

"https": "……"

},

]

for i in urls:

# 从IP代理池中随机选择一个

proxies = random.choice(proxies_list)

get_douban_books(i, proxies)

3) robots.txt

robots.txt是一种存放于网站根目录下的文本文件,用于告诉爬虫此网站中的哪些内容是不应被爬取的,哪些是可以被爬取的。在网站域名后加上/robots.txt即可查看。爬取网站时应遵守规则。

Reference:

[1] Wes McKinney. 2017. Python for Data Analysis: Data Wrangling with Pandas, NumPy, and IPython, 2nd Edition [M]. O'Reilly Media, Inc.

[2] CSDN博客. Python博客[OL]. https://www.csdn.net/nav/python. 2020.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值