爬虫入门练习(一)

2017-09-15  本文已影响141人  Ivan_Lan

最近开始学python,看了廖雪峰老师的入门教程后,就在知乎上找了些入门项目来练手。由于比较感兴趣的是爬虫,于是跟着一些大神的文章敲代码。现在把自己跟着敲的代码和自己的一些理解注释,还有运行过程中出现的一些问题,都一并记录上传到简书上来,一来是自己整理笔记,二来是和大家分享学习过程的一些问题和见解。(刚刚入门python,笔记中难免出错,若有高手看到,还望批评指正,感谢!)

本练习的要点:学会使用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爬虫入门(一):爬虫基本结构&简单实例


本练习的要点:学会将抓取的数据以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爬虫入门(四):储存


本练习的要点:学会使用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爬虫(实战篇):妹子图爬虫,上车吧!


上一篇下一篇

猜你喜欢

热点阅读