python抓取网页数据
解析效率:正则表达式>lxml>beautifulsoup
爬取方式 | 正则表达式 | lxml | beautifulsoup |
---|---|---|---|
解析效率 | 高 | 中 | 低 |
复杂度 | 低 | 中 | 高 |
代码 | urllib2.urlopen(urllist).read() |
BeautifulSoup(html,'html.parser') |
lxml.html.fromstring(html) |
lxml库功能和使用类似BeautifulSoup库,不过lxml解析速度比beautifulsoup快。
爬取网页基础
requests_html下载
- 安装anaconda
pip install pipenv
- 运行完后运行:
pipenv install
pip install requests_html
爬取网站
from requests_html import HTMLSession session = HTMLSession() url = 'https://www.codekp.cn/' r = session.get(url) print(r.html.text) print(r.html.links) print(r.html.absolute_links)
r.html.text
为网页文本内容r.html.links
网页中包含的全部链接r.html.absolute_links
为网页中包含的绝对路径输出结果为网站链接,和我们想要的内容并不完全相符,因此为了达到获取关键信息的目的,我们还需要进一步研究。跟Python说清楚我们要找的东西。这是网页抓取的关键。
数据可视化pandas
只需要这一行命令,我们就能把刚才的列表变成数据框:
df = pd.DataFrame(get_text_link_from_sel(sel))
表头设置df.columns = ['text', 'link']
保存csv格式df.to_csv('output.csv', encoding='gbk', index=False)
代码
from requests_html import HTMLSession
session = HTMLSession()
url = 'https://www.codekp.cn'
r = session.get(url)
def get_text_link_from_sel(sel):
mylist = []
try:
results = r.html.find(sel)
for result in results:
mytext = result.text
mylink = list(result.absolute_links)[0]
mylist.append((mytext, mylink))
return mylist
except:
return None
# print(r.html.text)
# print(r.html.links)
# print(r.html.absolute_links)
sel = 'head > link:nth-child(22)'
results = r.html.find(sel)
print(results)
# sel = 'body > div.note > div.post > div.article > div.show-content > div > p > a'
print(get_text_link_from_sel(sel))
import pandas as pd
df = pd.DataFrame(get_text_link_from_sel(sel))
df.to_csv('output.csv', encoding='gbk', index=False)
print(df)
urllib 使用
urllib.request.urlopen() 模拟浏览器向服务器发送请求
response 服务器返回的数据
response的数据类型是HttpResponse
字节‐‐>字符串
解码decode
字符串‐‐>字节
编码encode
read() 字节形式读取二进制 扩展:rede(5)返回前几个字节
readline() 读取一行
readlines() 一行一行读取 直至结束
getcode() 获取状态码
geturl() 获取url
getheaders() 获取headers
urllib.request.urlretrieve()
通过urllib下载
import urllib.request
# 下载网页
# url_page = 'http://www.baidu.com'
# url代表的是下载的路径 filename文件的名字
# 在python中 可以变量的名字 也可以直接写值
# urllib.request.urlretrieve(url_page,'baidu.html')
# 下载图片
# url_img = 'https://img1.baidu.com/it/u=3004965690,4089234593&fm=26&fmt=auto&gp=0.jpg'
# urllib.request.urlretrieve(url= url_img,filename='lisa.jpg')
# 下载视频
url_video = 'https://vd3.bdstatic.com/mda-mhkku4ndaka5etk3/1080p/cae_h264/1629557146541497769/mda-mhkku4ndaka5etk3.mp4?v_from_s=hkapp-haokan-tucheng&auth_key=1629687514-0-0-7ed57ed7d1168bb1f06d18a4ea214300&bcevod_channel=searchbox_feed&pd=1&pt=3&abtest='
urllib.request.urlretrieve(url_video,'hxekyyds.mp4')
BeautifulSoup爬取辛巴克菜单
import urllib.request
from bs4 import BeautifulSoup
url = 'https://www.starbucks.com.cn/menu/'
response = urllib.request.urlopen(url)
content = response.read().decode('utf-8')
soup = BeautifulSoup(content,'lxml')
# //ul[@class="grid padded-3 product"]//strong/text()
name_list = soup.select('ul[class="grid padded-3 product"] strong')
for name in name_list:
print(name.get_text())
lxml获取百度一下
import urllib.request
url = 'https://www.baidu.com/'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36'
}
# 请求对象的定制
request = urllib.request.Request(url = url,headers = headers)
# 模拟浏览器访问服务器
response = urllib.request.urlopen(request)
# 获取网页源码
content = response.read().decode('utf-8')
# 解析网页源码 来获取我们想要的数据
from lxml import etree
# 解析服务器响应的文件
tree = etree.HTML(content)
# 获取想要的数据 xpath的返回值是一个列表类型的数据
result = tree.xpath('//input[@id="su"]/@value')[0]
print(result)