python抓取网页数据

解析效率:正则表达式>lxml>beautifulsoup

爬取方式 正则表达式 lxml beautifulsoup
解析效率
复杂度
代码 urllib2.urlopen(urllist).read() BeautifulSoup(html,'html.parser') lxml.html.fromstring(html)

lxml库功能和使用类似BeautifulSoup库,不过lxml解析速度比beautifulsoup快。

爬取网页基础

requests_html下载

  1. 安装anaconda
  2. pip install pipenv
  3. 运行完后运行: pipenv install
  4. pip install requests_html

    爬取网站

    1
    2
    3
    4
    5
    6
    7
    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)

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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 使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
urllib.request.urlopen() 模拟浏览器向服务器发送请求
response 服务器返回的数据
response的数据类型是HttpResponse
字节‐‐>字符串
解码decode
字符串‐‐>字节
编码encode
read() 字节形式读取二进制 扩展:rede(5)返回前几个字节
readline() 读取一行
readlines() 一行一行读取 直至结束
getcode() 获取状态码
geturl() 获取url
getheaders() 获取headers
urllib.request.urlretrieve()

通过urllib下载

1
2
3
4
5
6
7
8
9
10
11
12
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爬取辛巴克菜单

1
2
3
4
5
6
7
8
9
10
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获取百度一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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)