您现在的位置是:首页 >技术教程 >爬虫(数据采集与预处理课程)网站首页技术教程

爬虫(数据采集与预处理课程)

简介爬虫(数据采集与预处理课程)

01_urllib的基本使用.py 
import urllib.request

url = 'http://www.baidu.com'

# 模拟浏览器向服务器发送请求
response = urllib.request.urlopen(url)

# read()方法返回的是二进制数,所以没有中文
# 将二进制转换为对应页面的 'utf-8'格式字符串,采用decode('编码格式')方法进行解码
content = response.read().decode('utf-8')

print(content)

 

02_urllib的一个类型6个方法.py 

import urllib.request

url = 'http://www.baidu.com'

response = urllib.request.urlopen(url)
# 1个类型 6个方法
#  1个类型
# response是 <class 'http.client.HTTPResponse'>类型
# print(type(response))

#  方法1;一个字节一个字节的读
# content = response.read()
# print(content)

# 方法2:一次读5个节点,按5个字节返回 b'<!DOC'
# content = response.read(5)
# print(content)

# 方法3:读取一行并返回
# content = response.readline()
# content = response.readline().decode('utf-8')
# print(content)

# 方法4:读取多行,一行一行的,直到读完为止
# content = response.readlines()
# content = response.readlines()
# for i in content:
#     content_i = i.decode('utf-8')
#     print(content_i)

# 方法5:返回状态码,200,请求成功
print(response.getcode())
# 返回url地址
print(response.geturl())

# 方法6:返回源码的头部信息
print(response.getheaders())

 

03_urllib下载.py

# 1.下载网页
# url_page = 'http://www.baidu.com'
# urllib.request.urlretrieve(url=url_page, filename='package_data/baidu.html')

# 2.下载图片(重庆理工--概况)
# url_img1 = 'https://www.cqut.edu.cn/__local/4/DA/F0/8812C68194287927DE8FF8D50AD_4674267B_29387.jpg'
# urllib.request.urlretrieve(url=url_img1, filename='package_data/静心桥.jpg')

# url_img2 = 'https://www.cqut.edu.cn/__local/1/F5/7D/5803240837D03B0966EDFA4AA49_6931F9C4_167C4.jpg'
# urllib.request.urlretrieve(url=url_img2, filename='package_data/重庆理工大学.jpg')

# 3.下载视频
url_video = 'https://vd3.bdstatic.com/mda-jmkgrj68sngeq0jj/v1-cae/sc/mda-jmkgrj68sngeq0jj.mp4?v_f'
urllib.request.urlretrieve(url=url_video, filename='package_data/重庆理工_百度百科.mp4')

# response = urllib.request(url_video)

 

04_urllib请求对象的定制.py 

# 请求对象的定制

# UA反爬:
# User-Agent: 请求载体的身份标识
# 反UA反爬:伪装爬虫程序请求的UA

# UA介绍:
# User-Agent 用户代理,特殊字符串头,使得服务器能够识别客户使用的
#  操作系统及版本、CPU类型、浏览器及版本、浏览器内核、浏览器渲染引擎、浏览器语言、浏览器插件等
# 语法: request = urllib.request.Request()

# url的组成:
# url的组成分为6部分, url:协议、主机、端口号、路径、参数、描点
# https://www.baidu.com/s?wd=周杰伦
# https/http 协议  www.baidu.com 主机  443/80 端口号  s 路径  wd=周杰伦 参数  #描点

# 请求对象的定制
import urllib.request

url = 'https://www.baidu.com/'

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36'
}

# 请求对象的制作
request = urllib.request.Request(url=url, headers=headers)

# response = urllib.request.urlopen(url)
# content = response.read().decode('utf-8')

response = urllib.request.urlopen(request)
content = response.read().decode('utf-8')
print(content)

# 关于端口号
# http 80
# https 443
# mysql 3306
# oracle 1521
# redis 6379
# mongodb 27017

 

05_编码.py 

# 扩展:编码的由来
# 编码集的演变
# 由于计算机是美国人发明的, 因此, 最早只有127 个字符被编码到计算机里, 也就是大小写英文字母、
# 数字和一些符号, 这个编码表被称为ASCII 编码, 比如大写字母A 的编码是65 , 小写字母z 的编码是122 。
# 但是要处理中文显然一个字节是不够的, 至少需要两个字节, 而且还不能和ASCII编码冲突
# 所以, 中国制定了GB2312 编码, 用来把中文编进去。
# 全世界有上百种语言, 日本把日文编到Shift_JIS 里, 韩国把韩文编到Euc-kr 里, 各国有各国的标准,
# 就会不可避免地出现冲突, 结果就是, 在多语言混合的文本中, 显示出来会有乱码
# 因此, Unicode 应运而生。Unicode 把所有语言都统一到一套编码里, 这样就不会再有乱码问题了。
# Unicode 标准也在不断发展, 但最常用的是用两个字节表示一个字符( 如果要用到非常偏僻的字符,就需要4个字节)。
# 现代操作系统和大多数编程语言都直接支持Unicodeo
06_get请求的qutoe方法.py 
import urllib.request
import urllib.parse

# url = 'https://www.baidu.com/s?wd=周杰伦'

url_base = 'https://www.baidu.com/s?wd='

name = urllib.parse.quote('周杰伦')

url = url_base+name

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36'
}

request = urllib.request.Request(url=url, headers=headers)

response = urllib.request.urlopen(request)

content = response.read().decode('utf-8')

print(content)

 

07_post请求—百度翻译.py 

import urllib.request
import urllib.parse
import json

# 不简便的
url = 'https://fanyi.baidu.com/sug'

data = {
    'kw': 'spider'
}

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36'
}
# # post 请求的参数,必须要进行编码(经过 parse 拼接后),
# 还需要转换成 unicode 格式(使用encode方法。不编码运行会报错。
data = urllib.parse.urlencode(data)
print(data)  # kw=spider
data = data.encode('utf-8')
print(data)  # b'kw=spider'

# Request中的data数据只能是 utf-8的数据
request = urllib.request.Request(url=url, data=data, headers=headers)

response = urllib.request.urlopen(request)

content = response.read().decode('utf-8')
print(content)
print(type(content))  # <class 'str'>

# 将字符串变成——》json 对象,可打印输出中文,易理解
content = json.loads(content)
# json对象 -》 str

print(content)

# 总结:
# post 请求方式的参数,必须编码(unicode):data = urllib.parse.urlencode(data)
# 编码之后 必须调用 encode 方法:data = urllib.parse.urlencode(data).encode('utf-8')
# 参数是放在请求对象定制的方法中:request = urllib.request.Request(url=url,data=data,headers=headers)
# 对于 POST 请求,浏览器先发送 header,服务器响应 100 continue,浏览器再发送 data,服务器响应 200 ok(返回数据

 

08_post 请求——百度详细翻译.py 

import urllib.request
import urllib.parse
import json

url = 'https://fanyi.baidu.com/v2transapi?'
data = {
    'from': 'en',
    'to': 'zh',
    'query': 'spider',
    'simple_means_flag': 3,
    'sign': '63766.268839',
    'token': '2dac2c971cb3efc3bf92a75b4a821cd9',
    'domain': 'common'
}

data = urllib.parse.urlencode(data).encode('utf-8')

headers = {
    'Cookie': 'BIDUPSID=5A6E9AA16B822700E6B1B5BCBAEB42A3; PSTM=1665300815; BAIDUID=5A6E9AA16B822700F0BEF36080BA40F5:FG=1; REALTIME_TRANS_SWITCH=1; FANYI_WORD_SWITCH=1; HISTORY_SWITCH=1; SOUND_SPD_SWITCH=1; SOUND_PREFER_SWITCH=1; BDUSS=Zrc05Fc1BuSkZOZmtnS0pSb3ozZkZSTVoxdEY3LXJ1RGY4OVlNTTQzRGZxaUprRVFBQUFBJCQAAAAAAAAAAAEAAACoNrdlTEZUR1MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAN8d-2PfHftjN0; BDUSS_BFESS=Zrc05Fc1BuSkZOZmtnS0pSb3ozZkZSTVoxdEY3LXJ1RGY4OVlNTTQzRGZxaUprRVFBQUFBJCQAAAAAAAAAAAEAAACoNrdlTEZUR1MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAN8d-2PfHftjN0; BAIDUID_BFESS=5A6E9AA16B822700F0BEF36080BA40F5:FG=1; ZFY=dMmjgbKQv:BhDlnFAzZTuObNcb:A0jirgFibkr3r:AmC0c:C; BA_HECTOR=a4a4a0a52584842gala58heh1i0u6gn1m; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; PSINO=6; delPer=0; H_PS_PSSID=38185_36557_37559_38105_38350_37861_38174_38289_37930_38313_38285_38041_26350_22160_38283_37881; BCLID=7906657821198685889; BCLID_BFESS=7906657821198685889; BDSFRCVID=BKLOJexroG07VWbfBcBRUlQr__weG7bTDYrEOwXPsp3LGJLVFe3JEG0Pts1-dEu-S2OOogKKKmOTH1AF_2uxOjjg8UtVJeC6EG0Ptf8g0M5; BDSFRCVID_BFESS=BKLOJexroG07VWbfBcBRUlQr__weG7bTDYrEOwXPsp3LGJLVFe3JEG0Pts1-dEu-S2OOogKKKmOTH1AF_2uxOjjg8UtVJeC6EG0Ptf8g0M5; H_BDCLCKID_SF=tRAOoC_-tDvDqTrP-trf5DCShUFs3fnrB2Q-XPoO3KtbSx3Pbx5jLlDAhbQHyhRf5mkf3fbgy4op8P3y0bb2DUA1y4vp0tLeWeTxoUJ2-KDVeh5Gqq-KXU4ebPRiB-r9Qg-D5lQ7tt5W8ncFbT7l5hKpbt-q0x-jLTnhVn0MBCK0HPonHjL5jjvy3f; H_BDCLCKID_SF_BFESS=tRAOoC_-tDvDqTrP-trf5DCShUFs3fnrB2Q-XPoO3KtbSx3Pbx5jLlDAhbQHyhRf5mkf3fbgy4op8P3y0bb2DUA1y4vp0tLeWeTxoUJ2-KDVeh5Gqq-KXU4ebPRiB-r9Qg-D5lQ7tt5W8ncFbT7l5hKpbt-q0x-jLTnhVn0MBCK0HPonHjL5jjvy3f; Hm_lvt_64ecd82404c51e03dc91cb9e8c025574=1678760419; APPGUIDE_10_0_2=1; Hm_lpvt_64ecd82404c51e03dc91cb9e8c025574=1678762322; ab_sr=1.0.1_NDcxYjgzNDA5ZDRiNmJkNzBjNTFhMGQ4YjcyNWU5NDkzMzE5N2I2NmIzZDc2OGQ3ZTgyZTE5ZTFmY2M5M2U5NWE1MGJhOTcyZTljYzY3MDc5OTg4Mjk0ODUyZmEzNTRkYzRjM2EzNGNlZmRmOTJlODg5NmU1MWM5YWY2ODVjZWEzMmFjMmFmNDU1NzM1YTRmZjY2NzhkMGQ3OGZiZDBmZmU4YTBiMmFiZGQyMzYxZTdmY2NmYWUzOGEwZmE2ZTg5'
}

headers_all = {
    'Cookie': 'BIDUPSID=5A6E9AA16B822700E6B1B5BCBAEB42A3; PSTM=1665300815; BAIDUID=5A6E9AA16B822700F0BEF36080BA40F5:FG=1; REALTIME_TRANS_SWITCH=1; FANYI_WORD_SWITCH=1; HISTORY_SWITCH=1; SOUND_SPD_SWITCH=1; SOUND_PREFER_SWITCH=1; BDUSS=Zrc05Fc1BuSkZOZmtnS0pSb3ozZkZSTVoxdEY3LXJ1RGY4OVlNTTQzRGZxaUprRVFBQUFBJCQAAAAAAAAAAAEAAACoNrdlTEZUR1MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAN8d-2PfHftjN0; BDUSS_BFESS=Zrc05Fc1BuSkZOZmtnS0pSb3ozZkZSTVoxdEY3LXJ1RGY4OVlNTTQzRGZxaUprRVFBQUFBJCQAAAAAAAAAAAEAAACoNrdlTEZUR1MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAN8d-2PfHftjN0; BAIDUID_BFESS=5A6E9AA16B822700F0BEF36080BA40F5:FG=1; ZFY=dMmjgbKQv:BhDlnFAzZTuObNcb:A0jirgFibkr3r:AmC0c:C; BA_HECTOR=a4a4a0a52584842gala58heh1i0u6gn1m; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; PSINO=6; delPer=0; H_PS_PSSID=38185_36557_37559_38105_38350_37861_38174_38289_37930_38313_38285_38041_26350_22160_38283_37881; BCLID=7906657821198685889; BCLID_BFESS=7906657821198685889; BDSFRCVID=BKLOJexroG07VWbfBcBRUlQr__weG7bTDYrEOwXPsp3LGJLVFe3JEG0Pts1-dEu-S2OOogKKKmOTH1AF_2uxOjjg8UtVJeC6EG0Ptf8g0M5; BDSFRCVID_BFESS=BKLOJexroG07VWbfBcBRUlQr__weG7bTDYrEOwXPsp3LGJLVFe3JEG0Pts1-dEu-S2OOogKKKmOTH1AF_2uxOjjg8UtVJeC6EG0Ptf8g0M5; H_BDCLCKID_SF=tRAOoC_-tDvDqTrP-trf5DCShUFs3fnrB2Q-XPoO3KtbSx3Pbx5jLlDAhbQHyhRf5mkf3fbgy4op8P3y0bb2DUA1y4vp0tLeWeTxoUJ2-KDVeh5Gqq-KXU4ebPRiB-r9Qg-D5lQ7tt5W8ncFbT7l5hKpbt-q0x-jLTnhVn0MBCK0HPonHjL5jjvy3f; H_BDCLCKID_SF_BFESS=tRAOoC_-tDvDqTrP-trf5DCShUFs3fnrB2Q-XPoO3KtbSx3Pbx5jLlDAhbQHyhRf5mkf3fbgy4op8P3y0bb2DUA1y4vp0tLeWeTxoUJ2-KDVeh5Gqq-KXU4ebPRiB-r9Qg-D5lQ7tt5W8ncFbT7l5hKpbt-q0x-jLTnhVn0MBCK0HPonHjL5jjvy3f; Hm_lvt_64ecd82404c51e03dc91cb9e8c025574=1678760419; APPGUIDE_10_0_2=1; Hm_lpvt_64ecd82404c51e03dc91cb9e8c025574=1678762322; ab_sr=1.0.1_NDcxYjgzNDA5ZDRiNmJkNzBjNTFhMGQ4YjcyNWU5NDkzMzE5N2I2NmIzZDc2OGQ3ZTgyZTE5ZTFmY2M5M2U5NWE1MGJhOTcyZTljYzY3MDc5OTg4Mjk0ODUyZmEzNTRkYzRjM2EzNGNlZmRmOTJlODg5NmU1MWM5YWY2ODVjZWEzMmFjMmFmNDU1NzM1YTRmZjY2NzhkMGQ3OGZiZDBmZmU4YTBiMmFiZGQyMzYxZTdmY2NmYWUzOGEwZmE2ZTg5',
    'Host': 'fanyi.baidu.com',
    'Origin': 'https://fanyi.baidu.com',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36',
    'X-Requested-With': 'XMLHttpRequest'
}

request = urllib.request.Request(url=url, data=data, headers=headers)

response = urllib.request.urlopen(request)

content = response.read().decode('utf-8')

obj = json.loads(content)

print(obj)

# 下载数据到本地,返回的是阶分数据,所以要存为 json 文本
# open 方法默认情况下使用的是 gbk 编码 如果想要保存汉字,
# 则需要在 open 方法中写明编码格式为utf-8, 即 encoding = 'utf-8'

 

09_get 请求——ajax 数据采集(豆瓣电影).py 

import urllib.request
import urllib.parse
import sys


def get_data(i):
    params = {
        'type': 24,
        'interval_id': '100:90',
        'action': '',
        'start': i*20,
        'limit': 20
    }

    params = urllib.parse.urlencode(params).encode('utf-8')

    return params


def create_request(url, data):
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36',
        'X-Requested-With': 'XMLHttpRequest',
        'Host': 'movie.douban.com',
        'Referer': 'https://movie.douban.com/typerank?type_name=%E5%96%9C%E5%89%A7&type=24&interval_id=100:90&action='
    }

    request = urllib.request.Request(url=url, data=data, headers=headers)
    return request


def get_content(request):
    response = urllib.request.urlopen(request)
    return response.read().decode('utf-8')


def write_content(content, i):
    with open(f'package_data/douban{i}.json', 'w', encoding='utf-8') as f:
        f.write(content)

    # print(f'douban{i}.json下载完成')


def main(url, start_page, end_page):
    for i in range(start_page, end_page+1):
        # 这里获取 5页
        data = get_data(i)

        request = create_request(url, data)

        content = get_content(request)

        write_content(content, i)
        progress = int((end_page+1 - start_page) / (end_page+1 - i) * 100) / 10
        print("
", "Download progress: {}% ".format(progress), "=" * i * 2, end='')
        sys.stdout.flush()


if __name__ == '__main__':
    url = 'https://movie.douban.com/j/chart/top_list?'
    start_page = int(input('请输入起始页的页码'))
    end_page = int(input('请输入结束页的页码'))
    main(url, start_page, end_page)
10_处理访问异常URLError,HTTPError.py

# http 错误:http错误是针对 浏览器服务 连接到 服务器 而给出的错误提示。引导并告诉浏览者该页是哪里出了问题。
# 通过 try-except进行捕获异常。异常有两类:URLErrorHTTPError

import urllib.request
import urllib.error

url = 'https://beijing.8684.cn'

headers = {
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36',
}

try:
    request = urllib.request.Request(url=url, headers=headers)

    response = urllib.request.urlopen(request)
    content = response.read().decode('utf-8')

    print(content)

except urllib.error.HTTPError:
    print('系统正在升级中')
except urllib.error.URLError:
    print('你找的网页不存在')


 

11_使用urllib爬取北京公交线路信息.py 

import urllib.parse
import urllib.request
from bs4 import BeautifulSoup
from urllib.parse import urljoin
import csv

# bus-layer depth w120

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36',
    'Upgrade-Insecure-Requests': 1,
}

all_data_list = []


def get_page_url(urls):
    request = urllib.request.Request(url=urls, headers=headers)
    response = urllib.request.urlopen(request)
    # 获取了response响应后,的对象要先进行read()读取,然后在将其的内容进行解码
    page = response.read().decode('utf-8')

    soup = BeautifulSoup(page, 'html.parser')
    list_urls = soup.find('div', attrs={'class': 'list clearfix'})
    # print(list_urls)
    for a in list_urls:
        # print(a)
        # print(a.get('href').strip())
        # print(a['href'])
        urls = urljoin(url, a['href'])
        # print(urls)
        # break
        get_page_info(urls)


def get_page_info(urls):
    request = urllib.request.Request(url=urls, headers=headers)
    response = urllib.request.urlopen(request)

    page = response.read().decode('utf-8')
    soup = BeautifulSoup(page, 'html.parser')
    # print(soup.prettify())

    # 线路选择
    line_type = soup.select('div.layout-left > div > div.info > h1 > a ')[0].string
    # 这里是利用 select 方法进行查询 路径的检索
    # 为什么要用string select生成的是一个 tag 类,也可以看作是一个列表 要利用string或get_text()方法进行获取文本
    # print(line_type, line_type.string)
    # <a aria-label="市区普线,按回车键查看全部市区普线" class="category" href="/line1">[市区普线]</a> [市区普线]
    try:
        # 总里程
        mileage = soup.select('div.layout-left > div.change-info.mb20')[0].string
    except:
        mileage = ''

    # 使用BeautifulSoup的find()、find_all()方法爬取更多的相关数据

    # 线路名称
    line_list_name = soup.find('h1', {'class': 'title'}).a.previous_sibling.string
    # sibling 兄弟节点   previous 上一个 previous_sibling获取上一个兄弟节点  next_sibling

    info_list = soup.find('ul', {'class': 'bus-desc'})

    # 运行时间
    run_time = info_list.find_all('li')[0].string

    # 参考票价
    ticket = info_list.find_all('li')[1].string

    # 公交公司名称
    company = info_list.find_all('li')[2].text
    # print(company)
    # print(company.text)
    # print(company.string)
    # None 不用string用text的原因
    # <li><span tabindex="0">公交公司:</span><a aria-label="北京公交集团第四客运分公司(服务热线:010-68683295),
    # 按回车键查看全部北京公交集团第四客运分公司(服务热线:010-68683295)运营的公交线路。"
    # href="/g1" title="北京公交集团第四客运分公司(服务热线:010-68683295)">北京公交集团第四客运分公司(服务热线:010-68683295)</a></li>
    # 这里是 多层标签的嵌套使用 如果直接进行string的话,只能直接获取<li>这里的东西<span> 但是没有内容
    # 不能在多个标签嵌套下 使用string 获取每个标签下的 text文本  应该使用 text

    # 最后更新时间
    update_last = info_list.find_all('li')[3].div.previous_sibling.string  # 获取前一个兄弟节点

    # 爬取 往返线路名称 的 Tag标签 放入列表 line_name_list
    line_name_list = soup.find_all('div', {'class': 'trip'})

    # 爬取 往返线路站点 的 Tag标签 放入列表 line_list
    line_list = soup.find_all('div', {'class': 'bus-lzlist mb15'})

    # 存储 往线路
    wang_line_list = []
    # 存储 返线路
    fan_line_list = []

    # 往线路名
    wang_line_name = ''
    # 返线路名
    fan_line_name = ''

    # 遍历列表,使用 .string 方法获取标签中的数据,对数据进行拼接处理,格式化字段
    for i in range(len(line_list)):  # 为什么这里要使用for循环呢???
        # 使用for循环的原因:这里的line_list是获取的 find_all div class='trip'的内容 如果有返的就会不止一个
        # 往
        if i == 0:
            # 这里进行 wang_line_list的初始化
            wang_line_list = line_list[0].find_all(['li'])
            wang_line_name = wang_line_name + "(" + line_name_list[0].string + ")"
        # i == 1 返
        else:
            # 这里进行 fan_line_list的初始化
            fan_line_list = line_list[1].find_all('li')
            fan_line_name = fan_line_name + "(" + line_name_list[1].string + ")"

    wang_info = wang_line_name + "
"
    fan_info = fan_line_name + "
"

    # 获取公交线路往的站点数据
    for i in range(len(wang_line_list)):
        if i != (len(wang_line_list) - 1):
            if wang_line_list[i].find_all(['a']) != []:
                for k in wang_line_list[i].find_all(['a']):
                    if k.get('title'):
                        continue
                    else:
                        wang_info += wang_line_list[i].find_all(['a'])[0].string + ','
        else:
            wang_info += wang_line_list[i].string

    # 获取公交路线返的站点数据
    if len(fan_line_list) != 0:
        for i in range(len(fan_line_list)):
            if i != (len(fan_line_list) - 1):
                if fan_line_list[i].find_all(['a']) != []:
                    for k in fan_line_list[i].find_all(['a']):
                        if k.get('title'):
                            continue
                        else:
                            fan_info += fan_line_list[i].find_all(['a'])[0].string + ','
            else:
                fan_info += fan_line_list[i].string
    result_list = [line_list_name, line_type, run_time, mileage, ticket, company, update_last, wang_info, fan_info]
    print(result_list)
    all_data_list.append(result_list)


if __name__ == '__main__':
    url = 'https://beijing.8684.cn/'
    url_list = url + '/list%d'
    for i in range(1, int(input("请输入你想要爬取的个数")) + 1):
        urls = url_list % i
        get_page_url(urls)

    field_name = ["线路名称", "线路类型", "运行时间", "总里程", "参考票价", "公交公司", "最后更新", "公安叫线路-往", "公交线路-返"]

    # 存储路径
    path = 'package_data/beijingbus.csv'
    with open(path, 'w', newline='', encoding='utf-8-sig') as f:
        writer = csv.writer(f)
        writer.writerow(field_name)
        writer.writerow(all_data_list)

 

12_Selenium基本使用.py 

# from selenium import webdriver
# from selenium.webdriver.chrome.service import Service
# import time
#
# # 取消自动关闭
# options = webdriver.ChromeOptions()
# options.add_experimental_option('detach', True)
#
# driver = webdriver.Chrome(options=options)
#
# driver.get('http://www.baidu.com')
#
# time.sleep(3)
#
# print(driver.title)


from selenium import webdriver
from selenium.webdriver.chrome.service import Service

# 利用驱动创建 驱动对象
path = Service(r'package_data/chromedriver.exe')
browser = webdriver.Chrome(service=path)


url = 'https://www.jd.com'

browser.get(url)

content = browser.page_source
print(content)

 

13_Selenium元素定位.py 

from selenium import webdriver
from selenium.webdriver.chrome.service import Service

# 导入By包 进行对元素的定位
from selenium.webdriver.common.by import By

path = Service(r'package_data/chromedriver.exe')
browser = webdriver.Chrome(service=path)

url = 'https://www.baidu.com'
browser.get(url)

# 元素定位
# 利用 find_element(By.xx, 'xxxx')来进行对元素的定位

# 1. id 标签属性
# button = browser.find_element(By.ID, 'su')

# 2. name 标签属性
# button = browser.find_element(By.NAME, 'wd')

# 3. xpath语句
# button = browser.find_element(By.XPATH, '//input[@id="su"]')

# 4. tag_name 标签名
# button = browser.find_elements(By.TAG_NAME, 'input')
# 返回的是 列表 中有多个对象

# 5. bs4语句
# button = browser.find_element(By.CSS_SELECTOR, '#su')
# bs4 #->id  .->class

# 6. 连接文本 Link_text  也就是标签里面的文本内容
button = browser.find_element(By.LINK_TEXT, '新闻')

print(button)

 

14_selenium访问元素信息.py 

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By


# path = Service(r'package_data/chromedriver.exe')
browser = webdriver.Chrome(service=Service(r'package_data/chromedriver.exe'))

url = 'https://www.baidu.com'
browser.get(url)

input_text = browser.find_element(By.ID, 'kw')

print(input_text)

# xx.get_attribute('xx属性')  获取xx中的xx属性的值
print(input_text.get_attribute('class'))

# 获取标签的名字  tag_name
print(input_text.tag_name)

 

15_selenium交互.py

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
import time

options = webdriver.ChromeOptions()
options.add_experimental_option('detach', True)

browser = webdriver.Chrome(service=Service(r'package_data/chromedriver.exe'), options=options)

url = 'https://www.baidu.com'

browser.get(url)

time.sleep(2)

# 获取文本框对象
input = browser.find_element(By.ID, 'kw')

# 利用send_keys() 方法 输入你想要输入的内容
input.send_keys('数据采集')
time.sleep(2)

# 获取 百度一下 搜索按钮
button = browser.find_element(By.ID, 'su')

# 点击按钮
button.click()
time.sleep(2)

# 模拟js滚动,滑动到底部  这里就是写了一段js代码 后面进行调用
js_bottom = 'document.documentElement.scrollTop=100000'

# 执行js代码
browser.execute_script(js_bottom)
time.sleep(2)

# 获取 下一页按钮并 点击链接
# next = browser.find_element(By.XPATH, '//*[@id="page"]/div/a[10]')
next = browser.find_element(By.XPATH, '//a[@class="n"]')    # 找a标签 class="n" 的a标签
next.click()
time.sleep(2)

# 返回上一页
browser.back()
time.sleep(2)

# 返回第二页 forward() 是向之前的路径回溯  回到进入现在这个页面的 位置
# browser.forward()
# time.sleep(2)

# back() 就是一直向前 回溯
# browser.back()
# time.sleep(2)

# 再次模拟js滚动,滚到底部
browser.execute_script(js_bottom)
time.sleep(2)

 

16_selenium爬取淘宝数据.py 

# 需求,抓取目标页面商品的基本信息,包括
#  商品图片、商品名称、价格、销量、店铺、地址 等信息

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
# from pyquery import PyQuery
from bs4 import BeautifulSoup
# 引入WebDriverWait 用于等待特定的位置
from selenium.webdriver.support.wait import WebDriverWait

import time

# 创建浏览器对象
path = Service(r"package_data/chromedriver.exe")
browser = webdriver.Chrome(service=path)

# 添加反检测
browser.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
    "source":
    """
    Object.defineProperty(navigator, 'webdriver',{
    get: () => undefined
    })
    """
})

wait = WebDriverWait(browser, 15)

# 关键字
KEYWORD = 'ipad'

# https://uland.taobao.com/sem/tbsearch?keyword=ipad
# https://uland.taobao.com/sem/tbsearch?keyword=ipad&pnum=0
# https://uland.taobao.com/sem/tbsearch?keyword=ipad&pnum=1
# https://uland.taobao.com/sem/tbsearch?keyword=ipad&pnum=2
# 定义 index_page()方法,抓取商品列表页


def index_page(page):
    print("正在爬取第", page, "页")
    try:
        # 这里跟老师的不一样,是因为啊,我这边的请求链接不一样
        url = 'https://uland.taobao.com/sem/tbsearch?keyword={}&pnum={}'.format(KEYWORD, page)
        browser.get(url)
        time.sleep(8)
        get_products()
    except TimeoutError:
        index_page(page)


def get_products():
    html = browser.page_source

    # doc = PyQuery(html)
    # items = doc(".pc-search-items-list").find('li')
    #
    # for item in items:
    #     # 图片地址、商品价格、销售数量、商品标题、店铺名、店铺地址
    #     product = {
    #         'image': item.find('a>img').attr('data-src')
    #     }

    soup = BeautifulSoup(html, 'html.parser')
    lis = soup.find_all('li', attrs={'class': 'pc-items-item item-undefined'})
    for li in lis:
        img = li.find('img', attrs={'class': 'pc-items-item-img img-loaded'}).get('src')
        title = li.find('span', attrs={'class': 'title-text'}).string.strip()
        price = li.find('span', attrs={'class': 'coupon-price-afterCoupon'}).string.strip()
        price = "¥" + price
        seller = li.find('div', attrs={'class': 'seller-name'}).text.strip()
        # 这里前面有一些东西是我们不需要的
        seller = seller[1:]
        sell_info = li.find('div', attrs={'class': 'sell-info'}).string.strip()
        print([img, title, price, seller, sell_info])
        break


def main():
    MAX_PAGE = int(input("你想要爬取的页数"))
    for i in range(0, MAX_PAGE):
        index_page(i)
    browser.close()


# 主程序入口
if __name__ == '__main__':
    main()

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。