包、模块
理解:
#引入自定义模块
from test1 import t1 #从包导入模块 如果是在同一包内直接导入模块名即可
print(t1.add(1,2))
在其它程序中导入模块,相当于从文件夹test1导入t1.py
爬虫所需要的模块
#引入系统的模块
import sys
import os
#引入第三方模块
import bs4 #爬完后网页解析,获取数据
from bs4 import BeautifulSoup
import re #内置的 正则表达式,进行文字匹配
import urllib.request,urllib.error #内置的 制定url,获取网页数据
import xlwt #Excel操作
import sqlite3 #内置的 进行sqlite数据库操作
urllib
import urllib.request #内置的 制定url,获取网页数据
# #获取一个get请求 可以用作模拟用户真实登陆
# response = urllib.request.urlopen("http://www.baidu.com")
# print(response.read().decode('utf-8')) #read()方法默认以二进制方式输出
# #对获取到的网页源码进行utf-8解码
# # 获取一个post请求
# import urllib.parse # urllib.parse 模块提供了很多解析和组建 URL 的函数
# data = bytes(urllib.parse.urlencode({"hello":"world"}),encoding="utf-8") #bytes()方法转换为二进制包
# response = urllib.request.urlopen("http://httpbin.org/post",data = data)
# print(response.read().decode('utf-8'))
# #超时处理 结束循环或者不爬取这个网页了,可以再进行针对性爬取 一般设置3-5秒
# # timeout 如果网站设置超时或者识别了爬虫可能出现超时反映
# try:
# response = urllib.request.urlopen("http://httpbin.org/get", timeout=0.1)
# print(response.read().decode('utf-8'))
#
# except urllib.error.URLError as e:
# print("time out!")
# print(e)
# # 获取各种数据
# response = urllib.request.urlopen("http://www.baidu.com")
# print(response.status) #状态码 如200是正常 404 418被发现爬虫
# print(response.getheaders()) #获取所有 Response Headers信息
# print(response.getheader("Cache-Control")) #获取 Response Headers里某项信息
# #测试
# url = "http://httpbin.org/post"
# headers = { # 伪装Response Headers内信息(可以加入全部信息,注意“”) host
# "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36"
# }
# data = bytes(urllib.parse.urlencode({'name':'df'}),encoding='utf-8') #封装
# req = urllib.request.Request(url=url,data=data,headers=headers,method="POST") #封装请求对象 url data(POST请求数据) headers method(请求方式)
# response = urllib.request.urlopen(req)
# print(response.read().decode("utf-8"))
#简单实现
url = "http://www.douban.com"
headers = { # 伪装Response Headers内信息 host
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36"
}
req = urllib.request.Request(url=url,headers=headers) #封装请求对象 url data(POST请求数据) headers method(请求方式)
response = urllib.request.urlopen(req)
print(response.read().decode("utf-8"))
Beautifual Soup
简单理解
BeautifulSoup4将复杂HTML文档转换成一个复杂的树形结构,每个节点都是Python对象,所有对象可以归纳为4种:
-Tag 标签及其内容:拿到它所找到的第一个内容
-NavigableString 标签里的字符串
-BeautifulSoup 表示整个文档
-Comment 是一个特殊的NavigableString 输出的内容不包含注释符号
遍历文档树
.contents 和 .children
tag的 .contents 属性可以将tag的子节点以列表的方式输出:
字符串没有 .contents 属性,因为字符串没有子节点:
通过tag的 .children 生成器,可以对tag的子节点进行循环: (不是列表,需要通过循环)
print(bs.head.contents)
print(bs.head.contents[3])
for child in bs.head.children:
print(child)
更多内容搜索文档…
简单应用
# 模拟
from bs4 import BeautifulSoup
#模拟读取网页
file = open("./baidu.html","rb")
html = file.read().decode("utf-8")
bs = BeautifulSoup(html,"html.parser") #参数:解析类型,解析器
# #1.-BeautifulSoup 表示整个文档
# #print(bs) # 输出整个文档 (属性结构)
# print(type(bs)) # 输出 <class 'bs4.BeautifulSoup'>
# #2. - Tag 标签及其内容:拿到它所找到的第一个内容
# print(bs.title) # 输出 <title>百度一下,你就知道 </title>
# print(bs.a)
# print(bs.a.attrs) #得到标签内所有的属性,返回一个字典
# print(type(bs.a.attrs)) #输出 <class 'dict'>
# #{'class': ['mnav'], 'href': 'http://news.baidu.com', 'name': 'tj_trnews'}
# 3.NavigableString 标签里的字符串
# print(bs.title.string) # 输出 百度一下,你就知道
# print(type(bs.title.string)) # 输出 <class 'bs4.element.NavigableString'>
# #4.-Comment 是一个特殊的NavigableString 输出的内容不包含注释符号
# print(bs.a.string) #如果是注释符号内的,则跳过其内容
# print(type(bs.a.string)) #输出 <class 'bs4.element.Comment'>
#-----------------------------
#文档的遍历 遍历文档树
# print(bs.head.contents)
# print(bs.head.contents[3])
#
# for child in bs.head.children:
# print(child)
#文档的搜索
#1.find_all() #找到所有该标签
#字符串过滤:会查找与字符串完全匹配的内容
# t_list = bs.find_all("a") #标签是 a
# print(t_list)
#
# #正则表达式搜索
# import re
# t_list = bs.find_all(re.compile("a")) #标签里含有a
#
# #方法 :根据函数要求搜索
# def name_is_exist(tag):
# return tag.has_attr("name")
#
# t_list = bs.find_all(name_is_exist) #标签里有“name”属性的
#
# for item in t_list:
# print(item)
# 2.kwargs 参数
# t_list = bs.find_all(id = "head") #在比如# t_list = bs.find_all(href="http://news.baidu.com")
# for item in t_list:
# print(item) #标签下含有 id="head"内容及其子内容
#再比如
# t_list = bs.find_all(href="http://news.baidu.com")
# for item in t_list:
# print(item) #标签下含有 id="head"内容及其子内容
# t_list = bs.find_all(class_=True)
#
# for item in t_list:
# print(item) #标签中函数class属性内容及其子内容
#3.text参数
# t_list = bs.find_all(text="hao123")
# t_list = bs.find_all(text = ["hao123","fd","贴吧"])
# for item in t_list:
# print(item) #html文本里包括 "hao123","fd","贴吧" ,如果有则输出
#
# import re
# t_list = bs.find_all(text = re.compile("\d"))
# for item in t_list:
# print(item) #应用正则表达式查找文本里包含特定文本的内容(标签里的字符串)
# #注意是compile是包含 该输出为 hao123
#4.limit 参数 限定获取的个数
# t_list = bs.find_all("a",limit=3)
# for item in t_list:
# print(item)
#5.css选择器 返回的是列表,可以通过循环输出
# t_list = bs.select('title') #通过标签来查找
# t_list = bs.select('.mnav') #通过类名来查找 即包含class属性
# t_list = bs.select("#u1") #通过id来查找,即id='u1'
# t_list = bs.select("a[class='bri']") #通过属性来查找
# t_list = bs.select("head > title") #通过子标签来查找 子标签
t_list = bs.select(".mnav ~ .bri") #查找兄弟标签 该:查找类名 mnav同级标签bri
print(t_list[0].get_text()) #获取内容(list) 再获取内容
for item in t_list:
print(item)