Python 基于BS4————爬虫
1.前期基础准备知识
- css:层叠样式器,主要用于渲染网页展示内容
- 选择器
选择器 | 用法 |
---|---|
通配符选择器 | 用* 引用 |
类选择器 | . |
id选择器 | 每一个id都是唯一的,用#后面跟上id值 |
标签选择器 | 直接写标签名 |
父子选择器 | 前面是标签包含后面标签,如.a>h2 |
后代选择器 | 后面标签属于前面标签的孙子,如,.b li |
兄弟选择器 | 属于同一级的标签,如h1 ~ h6 |
相邻兄弟选择器 | 两个标签必须是同级上下行位置关系,如,h1+h6 |
nth-child 选择器 | 标签只识别同级关系,如,.b > ol>li:nth-child(3) ,表示li标签的第三个孩子 |
在css选择器中如果标签里有类属性又有id属性选择其一,如果既没有类属性又没有id属性,就直接用标签进行定位
2. 需要安装到的库
库 | 功能 |
---|---|
requests | 获取网络连接 |
beautifulsoup4 | 匹配网页源代码 |
lxml | 解析页面,容错性好速度快 |
openpyxl | 将获取到的数据持久化保存到excel文件 |
- 主要用到以上库,后期需要其它三方库的支持直接安装即可安装
3. 爬虫步骤
-
通过网页地址和requests三方库向服务器发送请求,服务器返回一个响应。
常见响应码:
响应码 对应状态 200 访问成功 403 访问的网站将爬虫封了 404 页面丢失 500 服务器出问题 -
将返回的页面源代码进行解析成html,用lxml解析
-
通过css选择器进行定位
- 获取数据
- 存储数据通常存入csv、excel文件
4. 通用爬取页面
对于一般页面的爬取不需要太多的技术知识,现在很多网页都有反爬虫机制。可以出现封闭ip地址。因此我们要尽量取隐藏我们的爬虫,把它伪装成和网页获取。
- User-Agent:进行伪装成浏览器,浏览器直接可以获取。
- Cookie:里面存储用户的一些数据通常包括账户、密码
下面以爬取通过爬取中国新文网进行展开讲解
- 导入包和建立链接
import requests
import re # 用于正则式匹配
import csv # 写入csv文件
from bs4 import BeautifulSoup # 解析页面
# 建立连接的网站
url = f'https://www.chinanews.com/scroll-news/news1.html?qq-pf-to=pcqq.group'
# 设置请求头伪装爬虫
headers = {'User-Agent': ' Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'}
# 通过requests库建立与服务器的连接
resp = requests.get(url=ulr, headres=headres)
# 打印状态码,查看是否成功建立连接
print(resp.status_code) # 返回200 表示建立成功
- 获取网页数据
-
获取网页上的类型
# 解决乱码问题 resp.encoding = 'utf-8' soup = BeautifulSoup(resp.text, 'lxml') # 把返回的字符串解析成html页面 # 通过css选择器进行定位 # 获取新闻类型 sort_list = soup.select('div.content_list > ul > li> div.dd_lm > a') # 返回一个列表,里面每一的元素为bs4.BeautifulSoup对象
-
获取标题
title_list = soup.select('div.content_list > ul > li> div.dd_bt > a')
- 获取发布时间
href_list = soup.select('div.content_list > ul > li> div.dd_bt > a')
- 获取新闻连接
href_list = soup.select('div.content_list > ul > li> div.dd_time> a')
- 保存数据
with open('new.csv', 'w', encoding='utf-8', newline='') as file:
writer = csv.writer(file) # 将数据写入csv文件
完整代码
"""
homework01-爬取图片所示的新闻类型、标题、链接、发布时间,
进行多页爬取,并且只能爬取当天发布的新闻(最后一步有点难度,大家仔细思考下)
Version:
Author:
Date:2021/8/17
"""
import requests
from bs4 import BeautifulSoup
import csv
import time
# 获取当前时间
local_time = time.localtime()
with open('new.csv', 'w', encoding='utf-8', newline='') as file:
writer = csv.writer(file)
writer.writerow(['类型', '标题', '链接', '发布时间'])
for page in range(1, 11):
url = f'https://www.chinanews.com/scroll-news/news{page}.html?qq-pf-to=pcqq.group'
headers = {
'User-Agent': '***************************'}
resp = requests.get(url=url, headers=headers)
# 解决乱码问题
resp.encoding = 'utf-8'
soup = BeautifulSoup(resp.text, 'lxml')
# 类型
sort_list = soup.select('div.content_list > ul > li> div.dd_lm > a')
# 标题
title_list = soup.select('div.content_list > ul > li> div.dd_bt > a')
# 链接
href_list = soup.select('div.content_list > ul > li> div.dd_bt > a')
# 发布时间
time_list = soup.select('div.content_list > ul > li> div.dd_time')
try:
for sort, title, href, time in zip(sort_list, title_list, href_list, time_list):
if time.text[:4] == f'{local_time.tm_mon}-{local_time.tm_mday}': # 只获取今天发生的新闻
href = 'https:' + href.attrs['href']
writer.writerow([sort.text, title.text, href, time.text])
# print(sort.text, title.text, href, time.text)
except:
pass
5. 用代理获取网页源代码
-
代理的好处:伪装自己的ip地址用其它地址帮你进行进行转化
-
代理一般都是需要付费才能够进行获取得到,比较好的如下:
检测生成的IP地址是否有效
# -*- coding: UTF-8 -*-
"""
此代码为代理IP可用性检测模块,可准确筛选出尚未失效IP
注:
1.此代码只针对TXT数据格式接口。
2.尚未失效IP不一定为爬虫可用IP
3.使用时,请调用check_ip(url),url为TXT数据格式接口地址
"""
import requests
import telnetlib
import re
from concurrent.futures.thread import ThreadPoolExecutor
# 请求接口,匹配出代理IP,多线程检测
def check_ip(url):
real_ip = []
# 检测代理IP是否失效
def telnet_ip(ip, port):
try:
telnetlib.Telnet(ip, port, timeout=1)
real_ip.append(f'{ip}:{port}')
except:
pass
while True:
try:
resp = requests.get(url)
# print(resp.text)
ip_data = re.findall('(\d+\.\d+\.\d+\.\d+):(\d+)', resp.text)
with ThreadPoolExecutor(max_workers=16) as pool:
for ip, port in ip_data:
pool.submit(telnet_ip, ip, port)
return real_ip
except:
pass
- 配置代理ip地址
from check_proxies import check_ip
import requests
from bs4 import BeautifulSoup
URL = '*******************************' # 购买生成ip代理的网址
ip_list = check_ip(URL)
print(ip_list)
flag = True
while flag:
for i in range(len(ip_list)):
doubna_url = 'https://movie.douban.com/top250'
headers = {'User-Agent': '*************************'
}
# 代理ip
proxy = {
'http': 'http://' + ip_list[i],
'http': 'https://' + ip_list[i]
}
try:
resp = requests.get(url=doubna_url, headers=headers, proxies=proxy, timeout=1)
if resp.status_code == 200:
print(resp.text)
flag = False
break
except:
print('Erro')
简单总结
网络数据的采集对以一个数据分析者来讲是一项非常重要的技能,方便我们对自己想要的数据进行获取以便于后期的分析。网络数据基本都是通过一些代理来实现,绝大部分网站都是有反爬虫来阻止爬虫造成平凡的访问,导致网络拥塞崩溃情况。对于爬虫者也还是需要尊重一些网络协议不要过度频繁的去进行访问网站,给服务器造成压力。