爬虫学习随笔
-
GET 方式: 访问某个网页前不需要在浏览器里输入链接之外的东西,因为我们只是想向服务器获取一些资源,可能就是一个网页。
-
POST 方式:访问某个网页前需要在浏览器里输入链接之外的东西,因为这些信息是服务器需要的。 比如在线翻译,我们需要输入点英文句子,服务器才能翻译吧
url : 网址
resp: 响应
decode():字节转字符串
请求过程剖析:
-
服务器渲染:在服务器那边直接把数据和HTML整合在一起 统一返回给浏览器
在页面源代码中能看到数据
-
客户端渲染:第一次请求只要一个html骨架 第二次请求拿到数据进行数据展示
在页面源代码中看不到数据
熟练使用浏览器抓包工具
http协议: 浏览器与服务器之间数据交互遵守的协议
请求头的重要内容
-
User-Agent: 请求载体的身份标识(用啥发送的请求)
-
Referer : 防盗链(这次请求是从哪个页面来的?反爬会用到)
-
cookie: 本地字符串数据信息(用户登录信息、反爬的token)
响应头的主要内容:
-
cookie: 本地字符串数据信息(用户登录信息、反爬的token)
-
各种神奇的莫名其妙的字符串
反爬请求头
反爬请求头(UA头)
即用这些可以反反爬操作不必在用它浏览器自带的代码
百度 PC UA
User-Agent: Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html
User-Agent: Mozilla/5.0 (compatible; Baiduspider-render/2.0; +http://www.baidu.com/search/spider.html
request
get() 能向服务器发送了一个请求,请求类型为 HTTP 协议的 GET 方式
post() 也能向服务器发送一个请求,请求类型是 HTTP 协议的 POST 方式
注:在地址栏里输的链接都是get()方式
import requests
url="https://www.sogou.com/web?query=周杰伦"
resp=requests.get(url)
print(resp)
print(resp.text) 注:拿到页面源代码(调用requests库)
若被默认程序自动进入,需将其源代码中的network的user-agent内容复制粘到原程序,即
import requests
url="http://www.sogou.com/web?query=周杰伦"
dic={
"user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36 Edg/95.0.1020.44"
}
resp=requests.get(url,headers=dic)
print(resp)
print(resp.text)
注:加上请求头让服务器信服
import requests
url='https://fanyi.baidu.com/sug'
s=input("请输入你要翻译的英文单词: ")
dat={
'kw': s
}
resp=requests.post(url,data=dat)
print(resp.json())
requests获取百度翻译,变量为s可以自己随意输入(灵活性),为post型不是get. 发送post请求:发送的数据必须是放在字典中,通过data参数传递。json:将服务器返回的内容直接处理成json()
注:URL中的 ?后面为参数
使用完毕后记得 resp.close()
数据解析与提取
re解析
正则表达式
代码 | 意义 |
---|---|
. | 匹配除换行符以外的任意字符 |
\w | 匹配字母或数字或下划线 |
\s | 匹配任意的空白符 |
\d | 匹配任意数字 |
\b | 匹配单词的开始或结束 |
^ | 匹配字符串的开始 |
$ | 匹配字符串的结束 |
\n | 匹配一个换行符 |
\t | 匹配一个制表符 |
注:大写为反义
代码 | 意义 |
---|---|
\D | 匹配非数字 |
\W | 匹配非字母数字或下划线 |
\S | 匹配非空白符 |
a|b | 匹配字符a或b |
---|---|
[ ] | 从文本第一个字符查找中括号内的有无匹配,有则输出,无则跳下一个字符 |
[^ ] | 匹配除了字符组中字符的所有字符 |
量词:控制面前的元字符出现的次数
* | 重复零次或更多次 |
---|---|
+ | 重复一次或更多次 |
? | 重复零次或一次 |
{n} | 重复n次 |
{n,} | 重复n次或更多次 |
{n,m} | 重复n到m次 |
贪婪匹配或惰性匹配
.* | 贪婪匹配 |
---|---|
.*? | 惰性匹配(查最短的数据) |
re模块
注:可以给正则前加r
findall :匹配字符串中所有的符合正则的内容
finditer:匹配字符串中的所有内容(返回的是迭代器) 从迭代器中的拿到的内容需要 .group()
search:找到一个结果就返回,返回的结果是match对象 拿数据需要.group()
match:是从头开始匹配
即 lst=re.findall(r"\d+","我的电话是:10086,他的是:10010")
预加载正则表达式:
obj=re.compile(r"\d+")
注:compile 函数用于编译正则表达式
compile为提取网址信息
re.s 匹配换行符
注:如想要提取正则语句中的指定信息,只需把该.*? 括起来,然后加上 ?p<> 其中<>里为指定信息的名称
提取信息思路
-
拿到页面源代码 requests
-
通过re来提取想要的有效信息 re
strip() :移除字符串头尾指定的字符(默认为空格或换行符)或字符序列。 注意:该方法只能删除开头或是结尾的字符,不能删除中间部分的字符
verify=Flase :去掉安全认证
resp.encoding='gb2312' :指定gb2312字符集 即和utf-8类似
html中:a标签表示超链接
注:如想将其写文件需 import csv
BS4
html:
<标签 属性="属性值">被标记的内容</标签>
<img src="xxx.jpg"/> 标记图片
<div> 标签可以把文档分割为独立的、不同的部分。它可以用作严格的组织工具,并且不使用任何格式与其关联
<a href='http://www.baidu.com'>周杰伦</a>
表示点击页面上的周杰伦 跳转到百度页面.href为子链接
tr 表示行(横着的行) td 表示列(竖着的列)
<td>标示行中的一个列,需要嵌套在<tr></tr>中间
img 元素向网页中嵌入一幅图像
1.拿到页面源代码
import requests
url="https://www.bilibili.com/video"
resp=requests.get(url)
print(resp.text)
2.使用bs4进行解析 拿到数据
解析数据步骤
1.把页面源代码交给BeautifulSoup进行处理 生成bs对象
2.从bs对象中查找数据 /find(标签,属性=值)/find_all(标签,属性=值)
such as(总):
import requests
from bs4 import BeautifulSoup
import csv
url="https://www.bilibili.com/video"
resp=requests.get(url)
f=open("菜价.csv",mode="w")
csvwriter=csv.writer(f)
page=BeautifulSoup(resp.text,"html.parser") #指定html解析器
#table=page.find("table",class_="hq_table")
#table=page.find("table",attrs={"class":"hq_table")
trs=table.find_all("tr")[1:] #拿到所有的数据行
for tr in trs: #遍历每一行
tds=tr.find_all("td") #表示每行中所有的td
name=tds[0].text #text表示拿到被标签标记的内容
low=tds[1].text
high=tds[2].text
csvwriter.writerow([name,low,high])
f.close()
print("over!")
注:加#的为二选一 该代码摘自哔哩搞搞菜价
抓取图片步骤
1.拿到主页面的源代码 然后提取到子页面的链接地址 href
2.通过href拿到子页面的内容 从子页面找到图片的下载地址 img→src
3.下载图片
先调取源代码
import requests
url="http://www.bizhi360.com/weimei/"
resp=requests.get(url)
resp.encoding="utf-8"
print(resp.text)
把源代码交给bs4
from re import findall
import requests
from bs4 import BeautifulSoup
from requests.api import request
url="http://www.bizhi360.com/weimei/"
resp=requests.get(url)
resp.encoding="utf-8"
#print(resp.text)
main_page=BeautifulSoup(resp.text,"html.parser")
alist=main_page.find("ul").find_all("img")
#print(alist)
for a in alist:
src=a.get("src") #通过get就可以拿到属性的值
img_resp=requests.get(src) #下载图片
img_name=src.split("/")[-1]
with open(img_name,mode="wb") as f: #将图片写入文件
f.write(img_resp.content) #img_resp.content拿的是字节
print("over",img_name)
print("all over")
注:若想将图片放入一个文件夹中 在with open语句中改为:
with open("img"+img_name,mode="wb") as f:
Xpath解析
from lxml import etree
xml=" .."
tree=etree.parse(xml)
result=tree.xpath("/book/name/text()")
#/表示层级关系 第一个/是根节点
print(result)
#text() 拿文本
// 指后代 即包括该目录下的所有
注:xpath的顺序是从1开始 非0
抓取信息步骤
1.找到页面的源代码
2.提取和解析数据
import requests
from lxml import etree
url="..."
resp=requests.get(url)
html=etree.HTML(resp.text)
#将源代码文本扔到etree中解析数据
案例
from cgitb import html
from turtle import title
from unicodedata import name
import requests
from lxml import etree
url="https://www.zbj.com/search/f/?kw=%E6%95%B0%E6%8D%AE%E5%A4%84%E7%90%86"
resp=requests.get(url)
html=etree.HTML(resp.text)
#拿到每一个服务商
divs=html.xpath("/html/body/div[6]/div/div/div[2]/div[5]/div[1]/div")
for div in divs: #每一个服务商的信息
price=div.xpath("./div/div/a/div[2]/div[1]/span[1]/text()") [0].split("¥")
print("价格为:",price)
title=div.xpath("./div/div/a/div[2]/div[2]/p/text()") [0].split(",")
print("标题是:",title)
name=div.xpath("./div/div/a/div[1]/p/span//span/text()")
print("公司名称是:",name)
dizhi=div.xpath("./div/div/a/div[1]/div/span/text()")
print("地址为:",dizhi)
print(end="\n")
更新中......