自动采集编写(【soup】BeautifulSoupSoup的简单实用技巧,值得收藏!)
优采云 发布时间: 2022-02-10 00:03自动采集编写(【soup】BeautifulSoupSoup的简单实用技巧,值得收藏!)
BeautifulSoup 简介
Beautiful Soup 提供了简单的类似 python 的函数来处理导航、搜索、修改解析树等。它是一个工具箱,通过解析文档为用户提供他们需要抓取的数据。由于其简单性,无需太多代码即可编写完整的应用程序。
Beautiful Soup 自动将输入文档转换为 Unicode 编码,将输出文档自动转换为 utf-8 编码。不需要考虑编码方式,除非文档没有指定编码方式,否则Beautiful Soup无法自动识别编码方式。然后你只需要指定原创编码。
Beautiful Soup 已经成为与 lxml 和 html6lib 一样优秀的 python 解释器,为用户提供不同解析策略的灵活性或强大的速度。
BeautifulSoup findall()
find_all() 方法搜索当前标签的所有标签子节点,判断是否满足过滤条件:find_all(name,attrs,recursive,text,**kwargs)
name 参数可以找到所有名为 name 的标签,字符串对象会被自动忽略。它不仅可以传递字符串,还可以将列表/正则表达式/方法/布尔值/关键字参数作为参数来搜索标签
例子:
传入字符串:soup.find_all(["a","b"]) 传入正则表达式:soup.find_all(ple("^b")) 传入布尔值:传入soup.find_all(True) 方法:验证当前元素,如果收录class属性但不收录id属性,则返回True
def hac_class_but_no_id(tag):
return tag.has_attr('class') and not tag.has_attr('id)
soup.find_all(has_class_but_no_id)
指定 关键词:
soup.find_all(id='link2')
soup.find_all(href=re.compile("elsie") # 查找链接地址中带有elsie的标签
soup.find_all("a", class_="sister") # class_当作关键词
BeautifulSoup 对象
Beautiful Soup 将复杂的 HTML 文档转换成复杂的树形结构,每个节点都是一个 python 对象,所有对象可以总结为 4 个:
Tag:HTML 中的标签 NavigableString:标签内的非属性文本 BeautifulSoup:对象标识文档的全部内容 Comment:标签注释文本
对于 Tag,他有两个重要的属性,name 和 attrs:
打印汤.名称 | 打印汤.p.attrs | print soup.head.name 等会输出所有属性;
例如,要单独获取一个属性,您可以使用 get 或通过选择:
打印soup.title.get('class') | 打印soup.title['class']
代码展示
免费代理 ip URL:
代理 ip 活跃度检测:或
import requests
from bs4 import BeautifulSoup
import re
import signal
import sys
import os
import random
list = [
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1",
"Mozilla/5.0 (X11; CrOS i686 2268.111.0) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11",
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1092.0 Safari/536.6",
"Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1090.0 Safari/536.6",
"Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/19.77.34.5 Safari/537.1",
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.9 Safari/536.5",
"Mozilla/5.0 (Windows NT 6.0) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.36 Safari/536.5",
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
"Mozilla/5.0 (Windows NT 5.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
"Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3",
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3",
"Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
"Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.0 Safari/536.3",
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24",
"Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24",
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36"
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:88.0) Gecko/20100101 Firefox/88.0"
]
def handler(signal_num, frame): # 用于处理信号
Goduplicate()
print("\nDone,the available ip have been put in 'proxy_ips.txt'...")
print("\nSuccessed to exit.")
sys.exit(signal_num)
def proxy_spider():
headers = {"User-Agent": random.choice(list)} # 随机User-Agent
for i in range(20): # 爬取前20页
url = 'https://www.kuaidaili.com/free/inha/' + str(i + 1) + '/'
r = requests.get(url=url, headers=headers)
html = r.text
# print(r.status_code)
soup = BeautifulSoup(html, "html.parser")
datas = soup.find_all(name='tr')
for data in datas: # 根据页面特征来匹配内容
soup_proxy = BeautifulSoup(str(data), "html.parser")
proxy_contents = soup_proxy.find_all(name='td')
try:
ip_org = str(proxy_contents[0].string)
port = str(proxy_contents[1].string)
protocol = str(proxy_contents[3].string)
ip = protocol.lower() + '://' + ip_org
proxy_check(ip, port, protocol)
# print(ip)
except:
pass
def proxy_check(ip, port, protocol): # 代理存活检查
proxy = {}
proxy[protocol.lower()] = '%s:%s' % (ip, port)
# print(proxy)
headers = {"User-Agent": random.choice(list),
"Connection": "keep-alive"}
try:
r = requests.get(url='http://httpbin.org/get', headers=headers, proxies=proxy, timeout=5)
ip_available = re.findall(r"(?:[0-9]{1,3}\.){3}[0-9]{1,3}", r.text)[0] # 匹配ip
ip_availables = protocol.lower() + '://' + ip_available
# print(ip_availables)
# print(ip)
if ip_availables == ip:
print(str(proxy) + 'is ok')
with open("proxy_ip.txt", "a", encoding="utf-8") as ip:
ip.write(ip_available + ':' + port + '\n')
# else:
# print('no')
except Exception as e:
# print e
pass
def Goduplicate():
with open("proxy_ip.txt", encoding="utf-8") as urls:
url = urls.readlines()
new_url = []
for id in url:
if id not in new_url:
new_url.append(id)
for i in range(len(new_url)):
with open("proxy_ips.txt", "a") as edu:
edu.write(new_url[i])
os.remove("proxy_ip.txt")
if __name__ == '__main__':
signal.signal(signal.SIGINT, handler)
proxy_spider()
免费代理仍然不可靠。在这里爬了 20 个页面,捕获了 6 个可用的 IP:
代码还需要进一步优化。虽然爬取了20个页面,但是很多都因为访问速度太快被封杀了,作为分布式爬虫学习如何修改还是很有必要的。