python抓取网页数据( 使用Python语言的3个Python模块,抓取简书首页1000条文章与标题)
优采云 发布时间: 2021-11-15 23:18python抓取网页数据(
使用Python语言的3个Python模块,抓取简书首页1000条文章与标题)
使用 Python 语言作为抓取网络数据的工具很容易。正则表达式是一种可以高速匹配文本的操作。当正则表达式与 Python 结合时,会产生不同的火花。
在本文中,我们将使用一个简单的爬虫案例来抓取短书的页面,使用 requests 模块和 re 模块。在短书主页上获取 1,000 个 文章 链接和标题。
依赖库
本案例需要导入以下3个Python模块。
其中requests和fake_useragent不是Python标准库的模块。您可以在使用它们之前通过 pip 安装它们。
pip install requests -i http://pypi.douban.com/simple --trusted-host pypi.douban.com
pip install fake_useragent -i http://pypi.douban.com/simple --trusted-host pypi.douban.com
当然requests也可以换成urllib,主要用于请求页面和返回数据。
fake_useragent 的作用是自动生成一个用户代理。当然,您也可以使用自己浏览器的用户代理。
re 模块是 Python 标准库的常规模块。在这种情况下,它用于过滤数据。re模块的使用请参考作者之前的文章。
import re
import requests
import fake_useragent
查找界面
笔者推荐使用Chrome浏览器进行界面排查。
首先在Chrome中进入简书首页,按f12进入开发者工具状态,找到Network选项。
由于页面是通过滚轮滚动来实现加载数据的,所以笔者认为这是通过Ajax进行数据渲染。
Network下有一个XHR选项,这个选项就是页面上出现的所有Ajax接口。
对于爬虫工程师来说,最敏感的词之一就是page,即:页码。是的,Headers中Request URL的链接就是我们需要的接口。
构建请求头
关于请求头,我们需要构造:
# 实例化UserAgent对象
user_agent = fake_useragent.UserAgent(use_cache_server=False)
url = 'https://www.jianshu.com/?seen_snote_ids%5B%5D=66169577&seen_snote_ids%5B%5D=70078184&seen_snote_ids%5B%5D=59133070&seen_snote_ids%5B%5D=71131220&seen_snote_ids%5B%5D=69717831&seen_snote_ids%5B%5D=71082246&seen_snote_ids%5B%5D=69512409&seen_snote_ids%5B%5D=66364233&seen_snote_ids%5B%5D=68425069&seen_snote_ids%5B%5D=65829398&seen_snote_ids%5B%5D=70390517&seen_snote_ids%5B%5D=70715611&seen_snote_ids%5B%5D=60025426&seen_snote_ids%5B%5D=69454619&page={}'
# 请求头
headers = {
# 随机生成1个user-agent
'User-Agent': user_agent.random,
'X-Requested-With': 'XMLHttpRequest',
'Cookie': 'xxxxxxx',
}
# 设置代理(可省略)
proxies = {
'http': 'http://54.241.121.74:3128',
'https': 'http://54.241.121.74:3128'
}
需要注意的是url链接的page属性使用{}传递后续页码。
请求页面
首先,我们首先构造一个全局变量 num 来统计提取的数据。
num = 1
接下来是请求页面。
# 初始页码
count = 0
# 循环请求页面
while True:
response = requests.get(
# 传入页码
url=url.format(i),
headers=headers,
proxies=proxies
)
count += 1
# 解析页面
title_and_link = get_data(response.text)
# 展示数据
show_data(title_and_link)
# 如果judge为True,代表已经爬取了1000条数据
if num > 1000:
break
解析页面
def get_data(text):
"""
提取页面源码中的信息
:param text: 页面源代码
:return: result
"""
# 生成正则对象
pattern = re.compile(r'(.*?)', re.S)
# 查找符合上一行正则对象的数据
result = pattern.finditer(text)
return result
显示数据
def show_data(title_and_link):
"""
展示数据
:param title_and_link: 数据
:return: None
"""
# 重新声明num
global num
for i in title_and_link:
# 打印数据
print(f'{num}:https://www.jianshu.com{i.group(1).strip()}', end=' ')
print(i.group(2).strip())
num += 1
if num > 1000:
print('完成任务!!!')
break
结束语
这个爬虫程序比较简单,毕竟找到界面就可以一步一步的挖掘数据了。
其实这个爬虫程序有一些明显的bug,尤其是你没有设置cookies的时候。
是的,由于接口原因,当我们不设置cookies时,爬取的数据基本是重复的,cookies不能完美解决这个问题。当数据量较大时,即使设置了Cookie也会出现重复数据。
这个bug最直接的解决办法就是更换接口,但是这样做也意味着部分代码需要重构(虽然代码不多)。的确,通过 Chrome 的开发者工具,其他接口也存在,就看你能不能找到了。此外,使用硒也是一个不错的选择。这里也体现了爬虫程序的主观性,即实现功能的方式有很多种。但是我想说的是,既然提到了去重,那Redis怎么能丢呢?
没错,下一篇文章就是优化上面提到的爬虫程序去重复。
本文的完整代码可以在作者的GitHub下获取。