Hi~大家好!
本文会简单的爬取澎湃新闻网站的时事中国政库新闻,其中会涉及concurrent并发的简单应用!
一、分析网页
网址:
代码语言:javascript复制https://www.thepaper.cn/list_25462
澎湃新闻的网站有点像梨视频网站,想要获取更多的内容需要鼠标往下拉才会显示,是经过动态渲染而成,所以需要进入浏览器的开发者工具→Network→XHR
进行内容的抓包,得到了一条url。
打开该链接,得到的是一个简单静态网页:
每条链接的pageidx
参数和lastTime
参数会发生变化,其中pageidx
参数每次变化会增加1
,lastTime
是一个时间戳,这里不影响我们抓取内容,直接去掉就行了。
https://www.thepaper.cn/load_index.jsp?nodeids=25462&topCids=&pageidx=2&isList=true&lastTime=1616153518779
https://www.thepaper.cn/load_index.jsp?nodeids=25462&topCids=&pageidx=3&isList=true&lastTime=1616120430221
点开一条内容里面就是新闻信息了:
每条内容的链接都有特有的id
值,所以需要获取其id
值:
https://www.thepaper.cn/newsDetail_forward_11765286
https://www.thepaper.cn/newsDetail_forward_11763702
爬取思路:
- 请求动态加载出的链接
- 获取每条内容的特有的id值,拼接成内容的链接
- 提取新闻内容进行保存
二、实战代码
导入模块:
代码语言:javascript复制import requests
import re
from lxml import etree
import concurrent.futures
请求函数:
代码语言:javascript复制def def_response(url_s):
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36'
}
response = requests.get(url_s, headers=headers)
return response
保存函数:
代码语言:javascript复制def save(title_li, text):
# 声明编码,不然会报错
with open('./x.text', mode='a', encoding='utf-8')as f:
f.write(title_li 'nn')
f.write(text 'nn')
# 因为保存在一个文件中,所以这里用*号进行隔开
f.write('*' * 50 'nn')#
解析函数:
代码语言:javascript复制def main(html_url):
response = def_response(html_url)
href = re.findall('data-id="(.*?)"', response.text)
title = re.findall('alt="(.*?)"', response.text)
for url_li, title_li in zip(href, title):
# 拼接链接
url_ = f'https://www.thepaper.cn/newsDetail_forward_{url_li}'
res = def_response(url_)
etrees = etree.HTML(res.text)
# 这里用xpath提取文本内容,但是格式有点乱,所以用'nn'.join进行换行
text = 'nn'.join(etrees.xpath('.//div[@class="news_txt"]/text()'))
save(title_li, text)
启动器 :
代码语言:javascript复制if __name__ == '__main__':
# ThreadPoolExecutor 线程池的对象 max_workers 任务数 这里开了3个
executor = concurrent.futures.ThreadPoolExecutor(max_workers=3)
for page in range(0, 4):
url = f'https://www.thepaper.cn/load_index.jsp?nodeids=25462&topCids=&pageidx={page}&isList=true'
# main(url)
# submit 往线程池里面添加任务
executor.submit(main, url)
executor.shutdown()
效果图: