1.requests
先下载requests包
status_code返回200则请求成功,为400则失败
headers中若Content-Type没有编码信息,则会默认设为ISO-8859-1,中文可能会乱码,解决:将r,encoding设置为r.text中的chartset信息
encoding编码方式
text获取网页内容
import requests
url="http://www.crazyant.net"
r=requests.get(url)
print(r.status_code)#等于200则请求成功,为400则失败
print(r.headers)#若Content-Type没有编码信息,则会默认设为ISO-8859-1,中文可能会乱码,解决:将r,encoding设置为r.text中的chartset信息
print(r.encoding)#编码方式
print(r.text)#获取网页内容
print(r.cookies)
cookies辨别用户身份,故requests请求时常常需要附带cookies字典
#requests请求时附带cookies字典
import requests
cookies={
"Hm_lvt_4c9637db87f741d7588ff42a2a9c057d":"1669291068",
"Hm_lpvt_4c9637db87f741d7588ff42a2a9c057d":"1669292442"
}
r=requests.get("http://url", cookies=cookies)
cookies来自所爬网页,如下:
2.url管理器
要防止重复爬取、支持新增和取出,取出时状态变为已爬取,新增时判断是否已经存在
数据存储方式:Python内存(运行完后数据会丢失)、redis、MySQL(表格形式)
url管理器:
class UrlManager():
def __init__(self):
self.new_urls=set()
self.old_urls=set()
def add_new_url(self,url):
if url is None or len(url)==0:
return
if url in self.new_urls or url in self.old_urls:
return
self.new_urls.add(url)
def add_new_urls(self,urls):
if urls is None or len(urls)==0:
return
for url in urls:
self.add_new_url(url)
def get_url(self):
if self.has_new_url():#如果容器中已经有这个url
url=self.new_urls.pop()
self.old_urls.add(url)#标记为已爬取
return url
else:
return None
def has_new_url(self):
return len(self.new_urls)>0
if __name__=="__main__":#当.py文件被直接运行时,以下代码块将被运行;当.py文件以模块形式被导入时,以下代码块不被运行。
url_manager=UrlManager()
url_manager.add_new_url("url1")
url_manager.add_new_urls(["url1","url2"])
print(url_manager.new_urls,url_manager.old_urls)
print("#"*30)
new_url=url_manager.get_url()
print(url_manager.new_urls,url_manager.old_urls)
print("#"*30)
new_url=url_manager.get_url()
print(url_manager.new_urls,url_manager.old_urls)
print("#"*30)
print(url_manager.has_new_url())
正则表达式实现模糊匹配
#正则表达式实现模糊匹配
url1="http://www.crazyant.net/123.html"
url2="http://www.crazyant.net/123.html#comments"
url3="http://www.baidu.com"
import re
pattern=r'^http://www.crazyant.net/\d+.html$'#\d表示一个数字,\d+表示很多数字,^和$保证是以html结尾
print(re.match(pattern, url1))
print(re.match(pattern, url2))
print(re.match(pattern, url3))
运行结果:
<re.Match object; span=(0, 32), match='http://www.crazyant.net/123.html'>
None
None
3.HTML超文本标记语言
使用标记标签来描述网页的一种语言,标签成对出现,有开始有结束
<a href='baidu.html' class='article_link'>百度</a>
网页解析器Beautiful Soup
安装:pip install beautifulsoup4
使用:import bs4 或者 from bs4 import BeautifulSoup
创建BeautifulSoup对象-搜索节点find_all、find-访问节点(名称、属性、文字):
#创建BeautifulSoup对象
#创建BeautifulSoup对象
from bs4 import BeautifulSoup
soup=BeautifulSoup(
html_doc, #html文档字符串
'html.parser', #html解析器
from_encoding='utf-8' #html文档的编码
)
#搜索节点
#搜索节点
#查找标签为a的节点
soup.find_all('a')
#查找标签为a,链接符合/view/123.html形式的节点
soup.find_all("a",herf='/view/123.html')
#查找标签为div,class为abc(此处加下划线似乎因为与python关键字冲突了),文字为Python的节点
soup.find_all('div',class_='abc',string='Python')
#访问节点信息
#访问节点信息
#获取节点标签名
node.name
#获取节点的href属性
node['href']
#获取节点的链接文字
node.get_text()
举例:
HTML:
<HTML>
<head>
<meta http-equiv=Content-Type content="text/html;charset=utf-8">
<title>网页标题</title>
<body>
<h1>标题1</h1>
<h2>标题2</h2>
<h3>标题3</h3>
<h4>标题4</h4>
<div id="content" class="default">
<p>段落</p>
<a href='http://www.baidu.com'>百度</a>
<a href='http://www.iqiyi.com'>爱奇艺</a>
</div>
</body>
</HTML>
python:
from bs4 import BeautifulSoup
with open("./x.html",'r', encoding='utf-8') as fin:
html_doc=fin.read()
soup=BeautifulSoup(html_doc,"html.parser")
div_node=soup.find("div",id="content")#可先查大的区域块,再查找里面的细节
print(div_node)
print("#"*30)
links=div_node.find_all("a")
for link in links:
print(link.name,link["href"],link.get_text())
运行结果:
<div class="default" id="content">
<p>段落</p>
<a href="http://www.baidu.com">百度</a>
<a href="http://www.iqiyi.com">爱奇艺</a>
</div>
##############################
a http://www.baidu.com 百度
a http://www.iqiyi.com 爱奇艺