爬虫能让我们轻松、高效地获取网页上的数据,但写好一个爬虫并不是一件可以一蹴而就的事,现在来介绍一个简单爬虫的写法。
获取页面:resp = request.get(url)
这样就可以得到网页中的resp.text数据,下面是代码示例
import requests
resp = requests.get('https://sohu.com/')
print(resp.status_code) # 获取响应码 200则表示成功
print(resp.text) # 打印获取的数据
用上面的方法获取的信息也许并非全部是我们想要的,那么怎样从中筛选出我们想要的信息呢,下面介绍两种方法:
正则表达式解析:re.compile('...') ---> Pattern ---> findall / match / search
CSS选择器解析:BeautifulSoup4 ---> BeautifulSoup ---> select ---> Tag ---> text / attrs
然而这两种方法都需要对网页的页面布局进行解析,需要一定的前端知识,这里选用比较简单的方法,以Chrome浏览器为例,进入刚才获取信息的网页,按F12(或者从菜单栏中寻找)使用开发者工具。
这里顺便提点别的东西,在后面的分析中也用得到。
进入开发者工具后,从顶侧菜单栏中选择 Network
此时的下侧显示栏中可能没有什么内容 我们刷新一下页面
这时我们能看到一堆东西,这就是我们请求页面时获取到的所有参数
让我们点击第一个(www.sohu.com),看一看到底发生了什么
这里就是我们请求页面时的常规属性、响应头和请求头。这里有不少有用的信息可以在后续操作中用到。
让我们回到顶侧菜单栏 ,点击Elements。
在这里我们能看到整个页面的源代码,鼠标指向其中的标签,就能看到这部分在描述网页的哪一部分(在网页中以浅蓝色阴影标出)。当然,你也可以用鼠标指向你想要获取的信息,右键点击,在右键菜单栏中找到检查选项,可以直接跳转到源代码的这一部分。
知道了如何筛选我们想要的信息后,来实际操作一下。
如果我们想要获取标签中包含的所有链接信息,那么用正则表达式和CSS选择器该如何表示,下面直接贴代码。
import re
import requests
resp = requests.get('https://sohu.com/')
# print(resp.status_code)
# print(resp.text)
if resp.status_code == 200:
pattern = re.compile(r'\') # 正则表达式 匹配a标签中的链接部分
for result in pattern.findall(resp.text):
print(result)
else:
print('获取网页失败!')
import bs4
import requests
resp = requests.get('https://sohu.com/')
if resp.status_code == 200:
soup = bs4.BeautifulSoup(resp.text, 'html.parser')
# select方法会通过CSS选择器定位页面元素
anchors = soup.select('a[href]')
for anchor in anchors:
# 通过标签对象的attrs属性的索引操作获取指定的属性
print(anchor.attrs['href'])
else:
print('无法获取页面')
其中BeautifulSoup4是需要自行安装的第三方库。
上面已经介绍了获取网页数据并进行分析的基础操作,但这些在我们的实际应用中是远远不够的,实际应用中我们会遇到来自网站的各种反爬措施,具体的情况具体分析,下面举出了一些例子。
既然已经提到了实际应用,那我们拿到的东西不能光看,得保存下来吧?这里以Python读写Excel文件为例,需要用到第三方库,比如openpyxl、xlrd/xlwt、xlwings…这里以openpyxl为例,进行一个数据持久化(保存数据)的操作。
"""
爬取豆瓣电影Top250详情
"""
import random
import time
import bs4
import requests
import openpyxl
def fetch_movie_detail(detail_url):
resp = requests.get(
url=detail_url,
headers={
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36'
}
)
document = bs4.BeautifulSoup(resp.text, 'html.parser')
gener_spans = document.select('span[property="v:genre"]')
gener = ' / '.join([gener_span.text for gener_span in gener_spans])
country_span = document.select('span.pl')[4]
country = country_span.next_sibling.strip()
language_span = document.select('span.pl')[5]
language = language_span.next_sibling.strip()
duration = document.select_one('span[property="v:runtime"]').attrs['content']
return gener, country, language, duration
def main():
wb = openpyxl.Workbo