项目二 爬取数据

2024-10-10 18:30:55 浏览数 (1)

介绍

  • 该文章包含urllib、xpath爬取北京公交线路信息、selenium 爬取淘宝网站信息、scrapy 爬取北京公交信息

爬取北京公交线路信息

注意事项:网络爬虫需要确保网络稳定,不建议使用校园网,且本文爬取速度较慢,请耐心等待,若追求速度可使用多线程爬取

  • 本文章爬取北京公交线路信息有两种方法实现(课本使用urllib爬取)
  • 一种是通过urllib爬取,该方法主要实现于将数据爬取下来,保存在txt文件中
  • 一种是通过xpath爬取,具体参考以下文章(该文包括txt文本转换为csv文件,以及将文本文件加载到数据库中的实现过程)

urllib爬取

代码语言:python代码运行次数:0复制
import csv
import time
import urllib.request
from bs4 import BeautifulSoup as bs
from urllib.parse import urljoin

# 定义请求头,模拟浏览器访问
headers = {
   'User-Agent': 'Mozilla/5.0'
}

# 定义要爬取的网址
url = 'https://beijing.8684.cn/'
# 定义包含页面编号的URL模板
url_list = url   '/list%d'

def get_page_wangFan(wangFan_road_ol):
    # 获取网帆信息,参数为一个包含所有网帆信息的ol标签
    # 先获取第一个ol中的所有li元素
    wangFan_road_tmp = wangFan_road_ol[0].find_all('li')

    # 存储获取到的道路信息
    wangFan_road_lst = []
    for road in wangFan_road_tmp:
        temp = road.find('a')  # 查找li中的a标签
        if temp is None:
            continue  # 如果没有找到,跳过
        else:
            wangFan_road_lst.append(temp)  # 添加到列表中

    wangFan_road_lst.pop()  # 移除列表中的最后一个元素(无用项)
    try:
        # 获取第二个ol中的所有li元素(返回的信息可能有多个方向)
        wangFan_road_tmp = wangFan_road_ol[1].find_all('li')
    except:
        # 如果没有第二个ol,赋值为None
        wangFan_road_tmp = None

    if wangFan_road_tmp is not None:
        for road in wangFan_road_tmp:
            temp = road.find('a')  # 查找li中的a标签
            if temp is None:
                continue
            else:
                wangFan_road_lst.append(temp)  # 添加到列表中

    # 将所有获取到的道路名称合并为一个字符串
    wangFan_road = ""
    for r in wangFan_road_lst:
        wangFan_road  = r.string   ', '  # 用逗号分隔多个道路名

    # 返回所有道路的名称
    return wangFan_road


def get_page_info(urls):
    # 获取特定页面的详细信息
    rep = urllib.request.Request(url=urls, headers=headers)  # 创建请求
    html = urllib.request.urlopen(rep)  # 发送请求并获取响应
    soup = bs(html.read(), 'html.parser')  # 解析HTML

    # 提取公交线路的相关信息
    bus_name = soup.select('div.info > h1.title > span')[0].string  # 公交线路名称
    bus_type = soup.select('div.info > h1.title > a.category')[0].string  # 公交类型

    # 获取公交信息描述(时间、票价、公司、更新)
    time_select = soup.select('div.info > ul.bus-desc > li')
    bus_time = time_select[0].string  # 发车时间
    bus_ticket = time_select[1].string  # 票价
    gongsi = time_select[2].find('a').string  # 公司名称
    gengxin = time_select[3].find('span').string  # 更新时间

    try:
        licheng = soup.find('div', class_="change-info mb20").string  # 里程
    except:
        licheng = None  # 如果没有找到,赋值为None

    # 获取往车信息
    wang_info1 = bus_name  # 公交线路名称
    wang_info2 = soup.select('div > div > div.trip')[0].string  # 往程信息
    wang_total = soup.select('div > div > div.total')[0].string  # 往程总信息
    wang_road_ol = soup.find_all('div', class_='bus-lzlist mb15')[0].find_all('ol')  # 往程道路信息
    wang_road = get_page_wangFan(wang_road_ol)  # 获取往程的全部道路信息

    # 获取返程信息,可能不存在
    try:
        fan_info1 = bus_name  # 公交线路名称
        fan_info2 = soup.select('div > div > div.trip')[1].string  # 返程信息
        fan_total = soup.select('div > div > div.total')[1].string  # 返程总信息
        fan_road_ol = soup.find_all('div', class_='bus-lzlist mb15')[1].find_all('ol')  # 返程道路信息
        fan_road = get_page_wangFan(fan_road_ol)  # 获取返程的全部道路信息
    except IndexError:
        # 如果返程信息不存在,则所有相关信息赋值为None
        fan_info1 = None
        fan_info2 = None
        fan_total = None
        fan_road = None

    # 将所有获取到的信息整理成列表
    result_lst = [bus_name, bus_type, bus_time, bus_ticket, gongsi, gengxin, licheng, wang_info1, wang_info2,
                  wang_total, wang_road, fan_info1, fan_info2, fan_total, fan_road]

    # 将结果写入CSV文件
    cs = open('BeiJing_Bus_Info.txt', 'a', newline="", encoding='utf-8')
    writer = csv.writer(cs)  # 创建CSV写入器

    # 写入数据
    writer.writerow(result_lst)  # 将数据写入文件
    print(f"< - - - - - - - - - - - - - - - - - - - -  {bus_name}爬取完成  - - - - - - - - - - - - - - - - - - - -  >")
    time.sleep(1)  # 暂停1秒,避免过快请求导致被封

def get_page_url(urls):
    # 获取页面中的所有相关链接
    rep = urllib.request.Request(urls, headers=headers)  # 创建请求
    html = urllib.request.urlopen(rep)  # 发送请求并获取响应
    btsoup = bs(html.read(), 'html.parser')  # 解析HTML
    lu = btsoup.find('div', class_='list clearfix')  # 查找公交列表区域
    hrefs = lu.find_all('a')  # 获取所有链接
    for i in hrefs:
        # 对每一个链接进行处理
        urls = urljoin(url, i['href'])  # 处理相对链接并拼接成完整URL
        get_page_info(urls)  # 获取页面信息并存储到文件

if __name__ == '__main__':
    # 主程序入口,从第1页开始到第9页
    for k in range(1, 10):
        urls = url_list % k  # 构造当前页的URL
        time.sleep(1)  # 暂停1秒,避免过快请求
        get_page_url(urls)  # 获取当前页的所有公交信息
        print(f'爬取完第{k}个页面......')  # 输出当前爬取进度
  • urllib爬取结果输出(共计720 条数据)
  • 此处展示结尾部分数据
  • 若爬取过程中出现urllib.error.HTTPError: HTTP Error 503: Backend fetch failed,HTTP 503 错误通常是暂时的,可能是由于服务器过载或正在维护以及爬取网络和爬取速度相关(需要降低爬取速度),也有可能是因为请求头或IP被被封禁,换一个请求头或挂个VPN即可。实在解决不了,可通过本站联系我获取完整爬取数据。

xpath爬取

  • 此文在另外一个专栏(练手小项目),点击下面链接直达

https://cloud.tencent.com/developer/article/2451383

selenium 爬取淘宝网站信息

  • 此文在另外一个专栏(练手小项目),点击下面链接直达

https://cloud.tencent.com/developer/article/2451529

scrapy 爬取北京公交信息

  • 此文在另外一个专栏(练手小项目),点击下面链接直达

https://cloud.tencent.com/developer/article/2451533

0 人点赞