爬虫从入门到放弃(一)

分享一波爬虫从0.1到1的实战经验以及总结,特开此系列记录📝

为什么说是从0.1而不是0呢,因为当前仅有一些爬虫的基础知识而已,对于框架与实战经验的认知均为0。所以要是大佬打开了这篇文章,可能要让你失望了哈哈哈

每一个项目基本上都是边学边做,因为在实战中有很多坑,太少的知识储备让我在坑里爬不上来...希望各位看官也能从中学到东西!

ok,废话不多说,来看看爬虫坑的第一个实战项目-资讯爬取

目标地址:http://auto.gasgoo.com/comment/C-302-303-304/1

需要提取的数据:文章标题、文章摘要

要求:

  1. 只能用requests、re完成
  2. 爬取所有页码数的数据
  3. 提取的数据存入mysql

好了,清楚了要求以及需求,开始分析如何进行爬取。

根据聚焦爬虫流程,大致可分为四步

  1. 从url中提取响应内容
  2. 分析响应内容(页面),提取url,添加至urllist
  3. 从urllist中提取响应内容,提取数据
  4. 数据入库

1.从url中提取响应内容

爬取第一页试试

import requests
import re

url = "http://auto.gasgoo.com/comment/C-302-303-304/1"
content = requests.get(url).content.decode()
print(content)

ok,不需要添加headers即可爬取下来,可以开始分析怎么去获取我们的urllist了。

在分析之前,分享个小知识,我们获取页面响应内容有两个属性,response.text和response.content。那么一般使用哪个呢?

response.text 和response.content的区别

  • response.text
    • 类型:str
    • 解码类型: 根据HTTP头部对响应的编码作出有根据的推测,推测的文本编码
    • 如何修改编码方式:response.encoding=”gbk”
  • response.content
    • 类型:bytes
    • 解码类型: 没有指定
    • 如何修改编码方式:response.content.deocde(“utf8”)

而根据经验所得,怎么才能做到100%的解决乱码问题,按照以下步骤即可:

  1. 先使用decode()来尝试解码, 现在国内80%网站都是用utf-8进行编码的
  2. 如果上面面没有解决乱码问题,就指定GBK的编码方式, 个别网站使用的是GBK
  3. 如果指定GBK还不行,就request的自动推断功能了,通过text 属性获取

总结:更推荐使用response.content.deocde()的方式获取响应的html页面

2.分析响应内容(页面),提取url,添加至urllist

点击【下一页】,查看url是否会有变化

image-20190908125243463

发现url的末端变化了,变成了2,手动更改为1000,回车,跳转至1000页,那么确定了url,可以开始构建我们的urllist了。

import requests
import re

class Spider_news():
    #定义一个爬虫类
    baseurl = "http://auto.gasgoo.com/comment/C-302-303-304/{}"

    def __init__(self):
        #初始化方法
        content = requests.get(url=self.baseurl.format(1)).content.decode()
        self.end_page = re.search("href='/comment/C-302-303-304/(\d+)'>末页</a></div>",content).group(1)
        #print(self.end_page)


    def get_urllist(self):
        #生成urllist,从中提取url
        # urllist = []
        # for i in range(int(self.end_page)+1):
        #     urllist.append(self.baseurl.format(i))
        
        #用列表推导式更简洁一些
        return [self.baseurl.format(i) for i in range(1,int(self.end_page)+1)]

    def run(self):
        #启动爬虫主流程
        pass

if __name__ == '__main__':
    spider = Spider_news()
    spider.run()

这样第二步骤的代码已经完成了,拿到了urllsit。

3.从urllist中提取响应内容,提取数据

因为拿到了urllsit,所以每一页的响应内容都可以拿到了,接下来就是用re去提取我们想要的数据。注意了,坑来了!

image-20190908161440849

image-20190908161459959

我们可以看到第一页的前两条资讯,标题和摘要的html格式都是一致的,所以使用以下正则去提取我们需要数据

        for i in urllist:
            html = self.get_content(i)
            abstract = re.findall('<p class="details">(.*?)/p>',html)
            title = re.findall('shtml">(.*?)</a></h2>',html)
            print(abstract)
            print(title)

打印出来看一下

image-20190908162326281

可以发现,这正则并不能很好的匹配到我们想要的数据,看以下第三行中出现的a标签是怎么回事,根据上面代码我们知道,是第二页中的数据提取有问题,把a标签内容复制到第二页的网页源代码,看看这条正则怎么会匹配到这个a标签的。

image-20190908162555807

可以看到,第二页的这条资讯的摘要,和第一页中的摘要html格式是不一样的,无法使用这条正则去匹配,那么问题来了,正则应该怎么去修改呢?

看到这里,你们可以自己动手试试,看看能不能写出匹配到这两种格式的正则表达式。

到最后你会发现,一条正则是不可能匹配得了所有页面的资讯摘要。。。

因为有非常多不一样的格式,所以这里用正则去做就是一个坑!用xpath是最好的选择,这里非要用正则解决的话,就只能写两条去匹配,然后遍历得到的列表,再加进去一个新的摘要列表。

abstract_re = '<p.*?>([\s\S]*?)<a target="_blank" href="/[aN]'
abstract_re = '<p class="details">(.*?)/p>'

4.最后一步,数据入库

这边用的是pymysql连接mysql数据库

操作数据库的五个步骤:

  1. 连接数据库
  2. 获取游标
  3. 执行sql语句
  4. 提交事务
  5. 关闭游标,关闭数据库连接
import pymysql

def save_content(data):
    db = pymysql.connect("localhost", "root", "123456", "spider_data")  # 打开数据库连接
    cursor = db.cursor()   # 获取一个光标
    cursor.execute("INSERT INTO tencent__video_content(评论) values (%s)", (data))  # 执行sql语句
    db.commit()  # 涉及写操作要注意提交
    cursor.close()# 关闭游标/连接
    db.close()

那么先来总结一下,这次所遇到的坑。

  1. requests.content 和 requests.text的区别
  2. 正则提取的数据处理
    • .不支持匹配\n,导致有换行符的数据没匹配到
    • 使用正则\s\S当作.去使用
    • html转义字符的处理,比如\t什么的
      • 使用str.replace方法替换掉这些影响提取数据的字符
  3. 数据库入库中文乱码
    • 数据库的字符集需要设置为utf8
    • 字段字符集都需要设置为utf8mb4
    • 排序规则均为utf8_general_ci

ok,基本思路和遇到的坑都放上来了,完整代码就你们自己去完成吧,挺简单的。这次主要是为了学习基本爬虫的思路,入门的第一个小项目结束!!!

posted @ 2019-08-27 00:39 佑樹 阅读(...) 评论(...) 编辑 收藏