介绍
- 该文章包含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