Beautiful Soup是python的一个库,最主要的功能是从网页抓取数据,官方解释如下:
Beautiful Soup提供一些简单的、python式的函数用来处理导航、搜索、修改分析树等功能。它是一个工具箱,通过解析文档为用户提供需要抓取的数据,因为简单,所以不需要多少代码就可以写出一个完整的应用程序。
Beautiful Soup自动将输入文档转换为Unicode编码,输出文档转换为utf-8编码。你不需要考虑编码方式,除非文档没有指定一个编码方式,这时,Beautiful Soup就不能自动识别编码方式了。然后,你仅仅需要说明一下原始编码方式就可以了。
Beautiful Soup已成为和lxml、html6lib一样出色的python解释器,为用户灵活地提供不同的解析策略或强劲的速度。
关于爬虫利器urllib的用法详细见博客:http://cuiqingcai.com/947.html
其实就是根据URL来获取它的网页信息,虽然我们在浏览器中看到的都是浏览器解析后的画面,实质它是一段HTML代码,加 JS、CSS,如果把网页比作一个人,那么HTML便是他的骨架,JS便是他的肌肉,CSS便是它的衣服。所以最重要的部分是存在于HTML中的,下面我们就写个例子来扒一个网页下来。
关于这里补充的一点是:Python3中urllib的使用如下:
import urllib.request
response = urllib.request.urlopen("http://www.baidu.com")
from bs4 import BeautifulSoup
import urllib.request
import time,re
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
Python中socket模块的应用见博客:
http://blog.csdn.net/rebelqsp/article/details/22109925
import socket
socket.setdefaulttimeout(20) #对整个socket层设置超时时间。
def url_open(url):
req = urllib.request.Request(url)
req.add_header('User-Agent','Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.22 Safari/537.36 SE 2.X MetaSr 1.0')
因为服务器根据 user-agent 来判断拒绝了 python 爬虫,所以这里需要伪装成 chrome,来做浏览器登陆。
txt = page.read().decode('utf-8')
soup = BeautifulSoup(txt, 'lxml')
return soup
#封装问题的链接
page_url =[]
for num in range(1,45):
url = 'https://www.zhihu.com/topic/20047590/questions?page={}'.format(num)
soup = url_open(url)
urllist = soup.find_all(attrs={'class': 'question-item-title'})
time.sleep(10)
#print (urllist)
for i in urllist:
page =i.a['href']
#print ('https://www.zhihu.com' + page)
page_url.append('https://www.zhihu.com' + page)
我们获取数据的网址https://www.zhihu.com/topic/20047590/questions
这是首页,然后我们打开了第二页
由此我们得出了爬去前45页的代码
for num in range(1,45): url = 'https://www.zhihu.com/topic/20047590/questions?page={}'.format(num)
再下一句,我的理解就是获取网页源代码,就是那种一眼望过去崩溃的乱码样东西
soup = url_open(url)
注意观察每个问题前定义的类class,如官员贪污的金额真的那么低吗?,是属于<h2 class = 'question-item-title'>,变化的只有问题,所以又有了下一句代码:
urllist = soup.find_all(attrs={'class': 'question-item-title'}),意思是通过属性查找
这句代码帮我们爬取了所有的问题,仔细观察图片,在
官员贪污的金额真的那么低吗
这句话前面是href = /question/6066833,/quesiton/我就不解释了,我们姑且叫他page,至于这数字的作用以及这句代码,直接上图
page_url.append('https://www.zhihu.com' + page)
反正这段代码爬出来的是这么个意思:拿到网页是远远不够的,我们要看到是内容啊,下面看代码是不是就轻松多了,就解释下参数
所谓focus就是关注数,reviews是浏览,title就是标题啊def get_info(page_url): soup = url_open(page_url) titles= soup.find_all(attrs= {'class':'QuestionHeader-title'})[0].get_text() focus = soup.select('div.NumberBoard-value')[0].get_text() reviews = soup.select('div.NumberBoard-value')[1].get_text() frame = pd.DataFrame([titles, focus, reviews],index=['titles', 'focus', 'reviews']) # 转入数据列表 frame = frame.T return frame
继续看源码
socket.setdefaulttimeout(20) frame_list = list(map(get_info,page_url)) time.sleep(10) i, j, k = [], [], [] [(i.extend(x['titles'])) for x in frame_list] [(j.extend(x['focus'])) for x in frame_list] [(k.extend(x['reviews'])) for x in frame_list] df = pd.DataFrame([i, j, k], index=['titles', 'focus', 'reviews']) df1 = df.T print(df1)
没什么好说的,然后是完整的代码:
爬出来的结果是这样:# -*- coding: utf-8 -*- """ Spyder Editor This is a temporary script file. """ from bs4 import BeautifulSoup import urllib.request import time,re import pandas as pd import numpy as np import matplotlib.pyplot as plt import socket socket.setdefaulttimeout(20) #对整个socket层设置超时时间。 def url_open(url): req = urllib.request.Request(url) req.add_header('User-Agent','Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.22 Safari/537.36 SE 2.X MetaSr 1.0') page = urllib.request.urlopen(req) # 模仿浏览器登录 txt = page.read().decode('utf-8') soup = BeautifulSoup(txt, 'lxml') return soup #封装问题的链接 page_url =[] for num in range(1,45): url = 'https://www.zhihu.com/topic/20047590/questions?page={}'.format(num) soup = url_open(url) urllist = soup.find_all(attrs={'class': 'question-item-title'}) time.sleep(10) #print (urllist) for i in urllist: page =i.a['href'] print ('https://www.zhihu.com' + page) page_url.append('https://www.zhihu.com' + page) def get_info(page_url): soup = url_open(page_url) titles= soup.find_all(attrs= {'class':'QuestionHeader-title'})[0].get_text() focus = soup.select('div.NumberBoard-value')[0].get_text() reviews = soup.select('div.NumberBoard-value')[1].get_text() frame = pd.DataFrame([titles, focus, reviews],index=['titles', 'focus', 'reviews']) # 转入数据列表 frame = frame.T return frame socket.setdefaulttimeout(20) frame_list = list(map(get_info,page_url)) time.sleep(10) i, j, k = [], [], [] [(i.extend(x['titles'])) for x in frame_list] [(j.extend(x['focus'])) for x in frame_list] [(k.extend(x['reviews'])) for x in frame_list] df = pd.DataFrame([i, j, k], index=['titles', 'focus', 'reviews']) df1 = df.T print(df1)
来自微信公众号数据挖掘入门与实战