Python新手写出漂亮的爬虫代码

BeautifulSoup神器

Python一个第三方库bs4中有一个BeautifulSoup库,是用于解析html代码的,换句话说就是可以帮助你更方便的通过标签定位你需要的信息。这里只介绍两个比较关键的方法:

1、find方法和findAll方法:
首先,BeautifulSoup会先将整个html或者你所指定的html代码编程一个BeautifulSoup对象的实例(不懂对象和实例不要紧,你只要把它当作是一套你使用F12看到的树形html代码代码就好),这个实例可以使用很多方法,最常用的就是find和findAll,二者的功能是相同的,通过find( )的参数,即find( )括号中指定的标签名,属性名,属性值去搜索对应的标签,并获取它,不过find只获取搜索到的第一个标签,而findAll将会获取搜索到的所有符合条件的标签,放入一个迭代器(实际上是将所有符合条件的标签放入一个list),findAll常用于兄弟标签的定位,如刚才定位口碑信息,口碑都在dl标签下,而同一页的10条口碑对应于10个dl标签,这时候用find方法只能获取第一个,而findAll会获取全部的10个标签,存入一个列表,想要获取每个标签的内容,只需对这个列表使用一个for循环遍历一遍即可。

2、get_text()方法:
使用find获取的内容不仅仅是我们需要的内容,而且包括标签名、属性名、属性值等,比如使用find方法获取"<Y yy='aaa'>xxxx</Y>" 的内容xxxx,使用find后,我们会得到整个"<Y yy='aaa'>xxxx</Y>",十分冗长,实际我们想要的仅仅是这个标签的内容xxxx,因此,对使用find方法后的对象再使用get_text( )方法,就可以得到标签的内容了,对应到这里,我们通过get_text( )方法就可以得到xxxx了。

好了,铺垫做的差不多了,上代码咯~~~

案例:爱卡汽车

使用Python3,需要提前安装bs4库,博主的环境是win7+Python3+Pycharm(有时候也用Ubuntu16.04+Python3+Pycharm),很多时候都有人问博主,什么ide好用呢?jupyter notebook?spyder?Pycharm?这里只能和大家说各个ide各有千秋,做工程(如爬虫)使用pycharm肯定是首选,如果只是平时的练习,写个小程序,使用jupyter notebook和spyder就不错,总之,如果涉及到频繁打印输出结果的东西,最好还是用pycharm,不要用jupyter notebook,不然会很卡。

言归正传,上代码!

两点说明:爬虫代码中,html代码经常会出现’class’这个属性名,而class是python中“类”的关键字,而爬虫的find方法对于属性名而言,是不需要加引号的,如果直接输入class是会出现问题的,所以需要注意,每次输入class时应当输入为class_,即class后加一个下划线;

第二就是下方代码一开始有一个add_header的过程,为的是将代码伪装成浏览器。很多网站是反对爬虫程序对其信息进行爬取的,所以会禁止一些程序访问他们的网站,通过add_header将你的爬虫程序伪装成了浏览器,故在网站看来,访问它的就不是一个程序,而是一个浏览器,或者说是一个人类用户了。

import urllib
import urllib.request
from bs4 import BeautifulSoup
import re
import random
import time

# 设置目标url,使用urllib.request.Request创建请求
url0 = "http://newcar.xcar.com.cn/257/review/0.htm"
req0 = urllib.request.Request(url0)

# 使用add_header设置请求头,将代码伪装成浏览器
req0.add_header("User-Agent","Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36")

# 使用urllib.request.urlopen打开页面,使用read方法保存html代码
html0 = urllib.request.urlopen(req0).read()

# 使用BeautifulSoup创建html代码的BeautifulSoup实例,存为soup0
soup0 = BeautifulSoup(html0)

# 获取尾页(对照前一小节获取尾页的内容看你就明白了)
total_page = int(soup0.find("div",class_= "pagers").findAll("a")[-2].get_text())
myfile = open("aika_qc_gn_1_1_1.txt","a")
print("user","来源","认为有用人数","类型","评论时间","comment",sep="|",file=myfile)
for i in list(range(1,total_page+1)):
    # 设置随机暂停时间
    stop = random.uniform(1, 3)
    url = "http://newcar.xcar.com.cn/257/review/0/0_" + str(i) + ".htm"
    req = urllib.request.Request(url)
    req.add_header("User-Agent","Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36")
    html = urllib.request.urlopen(req).read()
    soup = BeautifulSoup(html)
    contents = soup.find('div', class_="review_comments").findAll("dl")
    l = len(contents)
    for content in contents:
        tiaoshu = contents.index(content)
        try:
            ss = "正在爬取第%d页的第%d的评论,网址为%s" % (i, tiaoshu + 1, url)
            print(ss)
            try:
                comment_jiaodu = content.find("dt").find("em").find("a").get_text().strip().replace("\n","").replace("\t","").replace("\r","")
            except:
                comment_jiaodu = ""
            try:
                comment_type0 = content.find("dt").get_text().strip().replace("\n","").replace("\t","").replace("\r","")
                comment_type1 = comment_type0.split("【")[1]
                comment_type = comment_type1.split("】")[0]
            except:
                comment_type = "好评"
            # 认为该条评价有用的人数
            try:
                useful = int(content.find("dd").find("div",class_ = "useful").find("i").find("span").get_text().strip().replace("\n","").replace("\t","").replace("\r",""))
            except:
                useful = ""
            # 评论来源
            try:
                comment_region = content.find("dd").find("p").find("a").get_text().strip().replace("\n","").replace("\t","").replace("\r","")
            except:
                comment_region = ""
            # 评论者名称
            try:
                user = content.find("dd").find("p").get_text().strip().replace("\n","").replace("\t","").replace("\r","").split(":")[-1]
            except:
                user = ""
            # 评论内容
            try:
                comment_url = content.find('dt').findAll('a')[-1]['href']
                urlc = comment_url
                reqc = urllib.request.Request(urlc)
                reqc.add_header("User-Agent",
                                "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36")
                htmlc = urllib.request.urlopen(reqc).read()
                soupc = BeautifulSoup(htmlc)
                comment0 = \
                soupc.find('div', id='mainNew').find('div', class_='maintable').findAll('form')[1].find('table',class_='t_msg').findAll('tr')[1]
                try:
                    comment = comment0.find('font').get_text().strip().replace("\n", "").replace("\t", "")
                except:
                    comment = ""
                try:
                    comment_time = soupc.find('div', id='mainNew').find('div', class_='maintable').findAll('form')[1].find('table', class_='t_msg').\
                    find('div', style='padding-top: 4px;float:left').get_text().strip().replace("\n","").replace( "\t", "")[4:]
                except:
                    comment_time = ""
            except:
                try:
                    comment = content.find("dd").get_text().split("\n")[-1].split('\r')[-1].strip().replace("\n", "").replace("\t","").replace("\r", "").split(":")[-1]
                except:
                    comment = ""
            # time.sleep(stop)
            print(user,comment_region,useful,comment_type,comment_time,comment, sep="|", file=myfile)
        except:
            s = "爬取第%d页的第%d的评论失败,网址为%s" % (i, tiaoshu + 1, url)
            print(s)
            pass
myfile.close()


补充说明一下:try——except这个结构(看起来有点像if——else的结构)是一个非常重要的过程,为了使爬虫代码可以良好的运行,不至于刚开始爬几分钟就报错这种恶心人的情况,需要很好的利用try——except过程。程序会先执行try下的语句,如果发生失败,就会执行except下的语句,你也可以使用多个try——except嵌套的结构完成复杂的情况的覆盖,最好要保证你的try——except过程包含了程序会遇到的所有情况,那么你的代码就是趋于完美的。

讲到这里,第一节爬虫课程也就到这里了,不久之后会介绍动态爬虫,如果之后还有时间,还会介绍一下selenium这个模拟浏览的库,以及爬虫框架还有反爬虫的知识,给自己打个广告,除了爬虫可,近期也会分享一些关于word2vec和fastText文本分类算法的内容,读者有什么其他想交流的可以留言~我也是个正在学习路上的仔,希望能和各路朋友以及大牛交流。

原文地址:点击打开链接

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值