使用python+BeautifulSoup 采集(爬虫)网站数据(实例+代码)

连接数据库,本文以MySQL为例

创建文件caijiMySQL.py ,连接数据库,代码如下:

import pymysql
def mysql_connect():
    db = pymysql.connect(host='数据库地址', port=3306, user='数据库账户', passwd='数据库密码', db='数据库名', charset='utf8')
    return db.cursor()

创建文件 caijiweb.py 用于采集网站信息,本文以采集河南省教育厅,教师招聘信息为示例,网址如下:http://www.haedu.gov.cn/jszp/index.html

分析所需采集对象的HTML节点

鼠标右键检查元素,或者按F12,可以查看当前页面的HTML元素。之后我们就要分析所采集的数据节点了。

如上图,我们以第一条信息为例,我们需要采集的是 class=”list” 下 <li> 标签下的信息,标题、链接、添加时间 。之后需要进去该页面,如下图:

如上图,我们进去后,可以以同样的方法获取到信息标签,比如 class = “det” 就是招聘内容。

如何获取对应节点下的信息?

这里我们就需要用到 俗称美味汤 的爬虫类库 beautifulsoup 了。这个类详细的使用方法在这里就不介绍了,可以参考之前的这篇文章,通过各种组合可以快速选择所需内容。

https://www.wushuai.net/archives/130

有哪些注意事项?

1、翻页:在上面第一张截图中,所需内容是有很多页的,所以需要翻页

2、采集过程中,有很多无用信息,所以需要筛选。比如我需要采集大学招聘老师的信息,其他的就没用了,无需再额外存储浪费空间。

3、数据库存储

4、要根据存储特点,对页面进行转译,比如 ‘ 要转移成 ‘ 以方便存储后在其他地方调取使用。

具体代码如下(附详细说明)

from bs4 import BeautifulSoup
from caijiMySQL import mysql_connect
# 引入第一步建立的数据库连接文件
import requests
#用于模拟网站请求
import re  #用于选择标签时的,正则选择
import time
#时间类
cursor = mysql_connect()
# 执行数据库连接

sql = "select insert_time from me_article limit 1"
values =cursor.execute(sql)
values = cursor.fetchall()
current_time = values[0][0]
#查一下最后一条插入的招聘信息是什么时间的,采集时,只采集这个时间点之后的数据。

def caiji_jiaoyu(url):
    wb_data = requests.get(url) #使用get方式获取页面内容
    wb_data.encoding = 'utf-8' #页面编码为utf-8
    soup = BeautifulSoup(wb_data.text, 'lxml') #使用美味汤进行分析性

    for child in soup.find_all('a',attrs={"target": "_blank"}): #获取页面所有链接
        article_html = requests.get(child['href']) #获取链接子页面内容
        re = article_html.status_code #子页面获取的状态,看是否获取成功
        if re == 200:
            article_html.encoding = 'utf-8'
            article_detail = BeautifulSoup(article_html.text, 'lxml')#分析子页面

            article_title= child.get_text()

            sql = "select * from me_article where article_name = %s"
            cursor.execute(sql, article_title)
            values = cursor.fetchall()  #查看是否已存在该招聘信息
            if values == ():
                result_a = article_title.find('学院')
                result_b = article_title.find('大学')
                result_c = article_title.find('学校')
                result_d = article_title.find('中学')
                result_e = article_title.find('中心')
                result_f = article_title.find('研究室')

                result = 0
                if result_a != -1:
                    result = result_a
                if result_b != -1:
                    if result < result_b:
                        result = result_b
                if result_c != -1:
                    if result < result_c:
                        result = result_c
                if result_d != -1:
                    if result < result_d:
                        result = result_d
                if result_e != -1:
                    if result < result_e:
                        result = result_e
                if result_f != -1:
                    if result < result_f:
                        result = result_f
                if result_a or result_b or result_c or result_d or result_e or result_f:# 筛选出大学招聘信息

                    sql = "select * from me_school where school_name = %s"
                    cursor.execute(sql,article_title[0:result+2])
                    values = cursor.fetchall()
                    if values != ():
                        school_id = values[0][0]
                    else:
                        sql = "insert into me_school(id, school_name) values (%s, %s)" #插入数据库
                        insert_result=cursor.execute(sql, ('', article_title[0:result+2]))
                        if insert_result == 1:
                            sql = "select * from me_school where school_name = %s"
                            cursor.execute(sql, article_title[0:result + 2])
                            values = cursor.fetchall()
                            if values != ():
                                school_id = values[0][0]
                        else:
                            school_id = 2
                    db.commit()

                article_time = article_detail.find("span",class_="time").get_text("|", strip=True)
                timeArray = time.strptime(article_time, "%Y-%m-%d %H:%M:%S")
                article_time = int(time.mktime(timeArray))
                if article_time < current_time:#如果发布时间比采集到的世界早,说明已经采集过了,是过时信息,跳出循环
                    exit()

                article_content_in = article_detail.select('.det')
                article_content_in_str = "".join('%s' % id for id in article_content_in)
                article_content = article_content_in_str.replace("'", "'")


                sql = "insert into me_article (school_id,article_name,article_content,article_url,article_time,insert_time) values (%s,%s,%s,%s,%s,%s)"
                cursor.execute(sql, (str(school_id), article_title, '<p>' + article_content + '</p>',child['href'], article_time, time.time()))

                db.commit()
#下方几行代码,为获取下一页链接,然后重复执行上面采集内容。一般是只在第一次采集时候使用。
    # if soup.find_all("a",text="下一页") != []:
    #     next_url = soup.find_all("a", text="下一页")[0].get('href').replace("tzgg", "/")
    #     url = 'http://www.haedu.gov.cn/jszp/' + next_url
    #     caiji_jiaoyu(url)

caiji_jiaoyu("http://www.haedu.gov.cn/jszp/index.html")
#执行采集

采集结果展示如下图:

注意,以上代码有部分是在博客编辑时加入的注释,如直接复制测试的话,请注意空格。

赞 (2)