爬虫入门练习(一)
2017-09-15 本文已影响141人
Ivan_Lan
最近开始学python,看了廖雪峰老师的入门教程后,就在知乎上找了些入门项目来练手。由于比较感兴趣的是爬虫,于是跟着一些大神的文章敲代码。现在把自己跟着敲的代码和自己的一些理解注释,还有运行过程中出现的一些问题,都一并记录上传到简书上来,一来是自己整理笔记,二来是和大家分享学习过程的一些问题和见解。(刚刚入门python,笔记中难免出错,若有高手看到,还望批评指正,感谢!)
-
爬虫入门练习1 :抓取厦大王亚南经济研究院老师信息:名字+个人主页链接--(来自知乎用户@iGuo)
本练习的要点:学会使用requests模块请求网页和使用BeautifulSoup模块解析网页,获取信息。
# conding=utf-8 # 声明utf-8编码方式
-------------------------------------------------------------------------------------------------
# 第一步: 利用request模块,请求网页
import requests # 导入requests模块 (requests模块用于请求网页)
r=requests.get('http://www.wise.xmu.edu.cn/people/faculty') # 调用get函数请求获得网页信息(函数内参数是目标网站)
html=r.content #采用 r.content方法,以二进制方式获取网页源代码
-------------------------------------------------------------------------------------------------
# 第二步,利用bs4解析库的BeautifulSoup模块,解析网页 ,并从网页源代码中找到我们需要的信息提取出来
from bs4 import BeautifulSoup # 从bs4库中导入Beautifulsoup模块
soup = BeautifulSoup ( html,'html.parser' ) # 解析网页:html是要解析的对象(第一步取得的html),html.parser是自己指定的解析器
div_people_list = soup.find ('div',attrs = {'class':'people_list'}) # 利用find方法,找到'div'标签且参数包含“class='people-list'的代码并返回(这里需要打开浏览器的审查元素,查看目标信息所在的位置对应的标签是什么,标签的属性是什么)
a_s = div_people_list.find_all ('a',attrs = { 'target': '_blank'}) # 利用find_all方法取出所有标签为'a'且参数包含的代码"target='_blank"的代码,返回的是一个列表。
for a in a_s: # for循环,a遍历a_s中的每个元素
url = a['href'] # 类似字典的索引取值,取出href对应的值
name = a.get_text() # 用get_text的方法把标签中的文本提取出来
print name,url # 打印名字:个人主页链接
-----------------------------------------------------------------------------------------------
详细的教程见知乎用户@iGuo 的文章:Python爬虫|Python爬虫入门(一):爬虫基本结构&简单实例
-
爬虫入门练习2 :抓取巨潮资讯网首页上市公司代码,名称,详细信息链接,并存入本地的csv文件--(来自知乎用户@iGuo)
本练习的要点:学会将抓取的数据以csv方式保存在本地电脑,并注意网页编码方式,python解释器编码方式,excel编码方式的不同。网页编码方式可以在设置中查看,Python解释器是默ASCII编码,excel是ASNI编码。
# -*- coding: utf-8 -*-
import requests # 导入requests模块
def getHTML(url): # 构造一个网页请求函数
r=requests.get(url) # requests请求后的网页内容赋给 r
return r.content # r.content表示二进制方式提取r 中的内容(还有r.text以文本方式提取)
# 上面的网页请求函数得到的网页源代码,即html,是下面网页解析函数的解析原材料
--------------------------------------------------------------------------------------------
from bs4 import BeautifulSoup # 从bs4库导入解析模块
def parseHTML(html): # 构造一个网页解析函数
soup=BeautifulSoup(html,'html.parser') # html代表要解析的文件,后面的参数指定了解析器,解析后的内容赋给soup
body=soup.body # 采用遍历方法,定位到 body标签(需打开浏览器点击审查元素,找到目标信息所在的标签)
company_middle=body.find('div',attrs={'class':'middle'}) # 采用find方法缩小范围,定位到标签div且属性为class="middle"的地方
company_list_ct=company_middle.find('div',attrs={'class':'list-ct'}) # 进一步缩小范围,定位到div且属性为class="list-ct"的地方
company_list=[] #将company_list 指向一个列表(构造一个空列表,等待后面添加进目标信息)
for company_ul in company_list_ct.find_all('ul',attrs={'class':'company-list'}): # 采用find_all定位到目标信息,返回的是列表形式的。for循环遍历此列表
for company_li in company_ul.find_all('li'): # find_all搜索定位到li标签所在位置,for遍历该标签信息
company_url=company_li.a['href'] # 用类似字典索引法,取标签值 , a是标签,href类似字典的键值
company_info=company_li.get_text() # 用get-text()方法获取标签中文本内容
company_list.append([company_info.encode('utf-8'),company_url.encode('utf-8')]) # encode 是对其进行utf-8 编码;此代码是将抓取的公司信息添加进前面建立的空列表
return company_list # 该解析函数返回一个列表,下面准备写入csv文件
-----------------------------------------------------------------------------------------
import codecs # 导入codecs模块, 用于转换编码
import csv # 导入csv模块,用于创建csv文件并写入数据
def writeCSV(file_name,date_list): # 构造写入函数,两个参数:文件名和数据列表
with codecs.open(file_name,'wb') as f: # 这里的codecs.open只传入两个参数(文件名和写入方式),第三个参数(编码方式)没传
writer=csv.writer(f) #
for data in data_list: # data遍历data_list列表中的数据
writer.writerow(data) # 逐行 将data写入文件
-------------------------------------------------------------------------------------------
# 以上是函数定义过程,下面是调用函数
URL='http://www.cninfo.com.cn/cninfo-new/information/companylist' #目标网站:巨潮资讯网
html=getHTML(URL) # 请求获得网页内容
data_list=parseHTML(html) # 对网页内容进行解析,提取数据,存入列表,赋值给data_list
writeCSV('test.csv',data_list) # 将抓取的数据写入csv文件
-------------------------------------------------------------------------------------------------
## 个人附注:
1,原作者在文章中说,在与代码同目录的文件夹找到数据文件,实际上我没找到,而是在notepad++的C盘安装文件夹里找到,可能个人原因。
2,运行过程有出现过报错:connection error,原因在于网址url输入错误导致无法访问目标网站。
3,运行过程出现了csv文件中只打印第一个公司:平安银行;原因在于:解析函数的return位置放在了for下,return对应的应该是解析函数,而不是for函数。
4,生成的csv文件先用记事本打开,另存为的时候选择编码ASNI,再用excel 打开就不会乱码了。
5,可在excel中对数据进行分列整理。
详细的教程见知乎用户@iGuo 的文章:Python爬虫|Python爬虫入门(三):解析和Python爬虫|Python爬虫入门(四):储存
-
爬虫入门练习3 :抓取妹子图网的美女图片并保存至本地文件夹
本练习的要点:学会使用requests请求网页,学会使用lxml库的html模块解析网页,并使用xpath语法选取所需要的信息。学会如何将抓取的图片下载到本地,包括文件夹命名,创建文件夹,写入文件。另外还有一个就是学会打印显示程序运行的状态。
# coding:utf-8 # 声明utf-8编码
import requests # 导入requests模块,用于请求网页
from lxml import html # 从lxml库导入html模块,用于解析网页
import os # 导入os模块,用于创建目录(文件夹)
import time # 导入time模块,暂停执行用(还不理解为何)
-------------------------------------------------------------------------------------------------
def getPage(pageNum): # 本函数目的:获取主页各图集的链接,为抓取图集的图片准备
baseUrl = 'http://www.mzitu.com/page/{}'.format(pageNum) # 考虑到主页的分页,构造链接,可翻页,输入第几页就爬第几页的链接
selector = html.fromstring(requests.get(baseUrl).content) # html直接解析requests请求到的网页信息
urls = [] # 构造空列表,用于添加抓取到的图集链接
for i in selector.xpath('//ul[@id="pins"]/li/a/@href'): # 使用xpath语法选取目标信息:图集链接(需了解xpath的语法才能理解)
urls.append(i) # 将图集链接添加进列表
return urls # 返回图集链接的列表
-----------------------------------------------------------------------------------------------
def getPiclink(url): # 本函数针对每一图集的链接,抓取其中的标题和其中的图片。url是详情页链接
sel = html.fromstring(requests.get(url).content) # 解析请求到的图集链接
total = sel.xpath('//div[@class="pagenavi"]/a[last()-1]/span/text()')[0] # xpath选取图集的页码数字
title = sel.xpath('//h2[@class="main-title"]/text()')[0] # xpath选取图集的标题
jpgList = [] # 构造列表用于添加图片jpg文件链接
for i in range(int(total)): # 本函数用于:构造图集里每一张图片的链接
link = '{}/{}'.format(url, i+1) # format函数用于格式化字符串,构造图集里的图片链接
s = html.fromstring(requests.get(link).content) # 直接解析图集的图片链接
jpg = s.xpath('//div[@class="main-image"]/p/a/img/@src')[0] # xpath选取到具体每一张图片的文件链接
jpgList.append(jpg) # 图片文件链接添加进列表
return title, jpgList #函数返回:图集标题,图片文件链接列表
# 注意,在详情页抓取下来的是,图片的链接,不是图片文件jpg。即某一图集的所有图片文件链接
-------------------------------------------------------------------------------------------------
def downloadPic((title, piclist)): # 本函数用于下载图片。传入函数是(标题,图片文件链接),元组的形式。
k = 1
count = len(piclist) # 计数;计算传进来的图片链接列表里的数量(实际上就是每一图集的数量)
dirName = u"【%sP】%s" % (str(count), title) # 文件夹名字(格式化字符串 )
os.mkdir(dirName) # 创建目录(文件夹)
for i in piclist: # 遍历图片链接列表里的图片链接
filename = '%s/%s/%s.jpg' % (os.path.abspath('.'), dirName, k) # 文件的绝对路径所在(文件写入的名称:当前路径/文件夹/文件名)
print u'开始下载图片:%s 第%s张' % (dirName, k) # 打印下载进度信息
with open(filename, "wb") as jpg: # 打开目标文件,准备写入
jpg.write(requests.get(i).content) # 请求获得图片文件链接,将图片写入文件
time.sleep(0.5) # 暂停运行0.5秒(不理解)
k += 1
if __name__ == '__main__': # 本代码的含义:若直接运行本代码,则执行下面的代码,若以导入形式执行,则不执行下面的代码。
pageNum = input('请输入页码:') # 想要抓取主页哪一页的图片链接(仅那一页)
for link in getPage(pageNum): # 遍历图片链接
downloadPic(getPiclink(link)) # 抓取图片文件链接,下载至本地
------------------------------------------------------------------------------------------------
## 个人附注:
1,经运行,发现,抓取的图片显示:勿盗链。。。可能遇到反爬虫。
2,出现过报错:windows error 183,原因:之前试运行创建了文件夹,文件夹已存在,故创建出错。
3,本代码可改进地方:本代码运行一次只抓取主页某一页的图集图片,假如要抓取1-10页的图片,需运行10次。或许可以改进成抓取第几页到第几页的图集图片。
详细的教程见知乎用户@yonggege的文章:Python爬虫(实战篇):妹子图爬虫,上车吧!