Python爬虫获取交通和污染物数据

Python爬虫获取交通和污染物数据

因为科研要用到交通平均车速和污染物浓度的数据,因而用了三天时间从零开始学习爬虫,但我之前已经有一点Python的基础。两个网站的数据都是每小时更新的,因此为了获取动态的数据和模拟点击的过程,这里用了selenium的包。
提前准备:

  1. 浏览器(我用的是CHROME)
  2. 浏览器对应的driver我用的是Chromedriver,这个可以在其他博主的文章里面查到,要注意对应好浏览器的版本,不然会报错。
  3. 安装selenium包(pip install selenium)

污染物爬虫

本来driver应该放在环境设置那里的PATH那里,但我放了还是报错,所以用了别的方法,直接就把driver所在文件夹的路径放上去了。代码如下,我用的是Anconda3 的spider:

import re
import time
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import pandas as pd
from bs4 import BeautifulSoup

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
#from selenium import webdriver
##import time
import datetime

flag = 0

now=datetime.datetime.now()
sched_timer = datetime.datetime(now.year,now.month,now.day,now.hour,now.minute,now.second)+datetime.timedelta(seconds=5)



    


def main():
    chrome_driver = 'D:\ChromeDriver\chromedriver_win32 (1)\chromedriver.exe'  #chromedriver的文件位置
    driver = webdriver.Chrome(executable_path = chrome_driver)

  
   
    driver.get('http://112.94.64.160:8023/gzaqi_new/RealTimeDate.html')
    driver.refresh()
    time.sleep(10)
    driver.refresh()
    time.sleep(30)
    element = driver.find_element_by_xpath('//*[@id="黄沙路边站"]')
    element.click()
    time.sleep(5)
    elements = driver.find_elements_by_xpath('//*[@id="areaName"]')
    f = open("E:/空气质量/污染物情况.txt","a")       
    for element in elements:
        print(element.get_attribute('innerHTML'))
        a = element.get_attribute('innerHTML')
    f.write(str(a))
    
    f.write("\n")
    element = driver.find_element_by_xpath('//*[@id="PM25"]')
    element.click()
    time.sleep(3)    
    elements = driver.find_elements_by_xpath('//*[@id="aqiValue"]')
    for element in elements:
        print(element.get_attribute('innerHTML'))
        b = element.get_attribute('innerHTML')
    f.write(str(b))
    f.write("\n")
    elements = driver.find_elements_by_xpath('//*[@id="pmtow"]')
    for element in elements:
        print(element.get_attribute('innerHTML'))
        c = element.get_attribute('innerHTML')
    f.write(str(c))
    f.write("\n")
    elements = driver.find_elements_by_xpath('//*[@id="pmtow_24"]')
    for element in elements:
        print(element.get_attribute('innerHTML'))
        d = element.get_attribute('innerHTML')
    f.write(str(d))
    f.write("\n")
    element = driver.find_element_by_xpath('//*[@id="PM10"]')
    element.click()
    time.sleep(3)    
    elements = driver.find_elements_by_xpath('//*[@id="pmten"]')
    for element in elements:
        print(element.get_attribute('innerHTML'))
        e = element.get_attribute('innerHTML')
    f.write(str(e))
    f.write("\n")
    elements = driver.find_elements_by_xpath('//*[@id="pmten_24"]')
    for element in elements:
        print(element.get_attribute('innerHTML'))
        y = element.get_attribute('innerHTML')        
    
    f.write(str(y))
    f.write("\n")
    element = driver.find_element_by_xpath('//*[@id="SO2"]')
    element.click()
    time.sleep(3)    
    elements = driver.find_elements_by_xpath('//*[@id="sotwo"]')
    for element in elements:
        print(element.get_attribute('innerHTML'))
        g = element.get_attribute('innerHTML')

    f.write(str(g))
    f.write("\n")
    element = driver.find_element_by_xpath('//*[@id="NO2"]')
    element.click()
    time.sleep(3)    
    elements = driver.find_elements_by_xpath('//*[@id="notwo"]')
    for element in elements:
        print(element.get_attribute('innerHTML'))
        h = element.get_attribute('innerHTML')
       
    f.write(str(h))
    f.write("\n")
    element = driver.find_element_by_xpath('//*[@id="CO"]')
    element.click()
    time.sleep(3)    
    elements = driver.find_elements_by_xpath('//*[@id="co"]')
    for element in elements:
        print(element.get_attribute('innerHTML'))
        j = element.get_attribute('innerHTML')        
        
    f.write(str(j))
    f.write("\n")
    element = driver.find_element_by_xpath('//*[@id="O3_1"]')
    element.click()
    time.sleep(3)    
    elements = driver.find_elements_by_xpath('//*[@id="othree"]')
    for element in elements:
        print(element.get_attribute('innerHTML'))
        k = element.get_attribute('innerHTML')             

    f.write(str(k))
    f.write("\n")
    f.close() #abcdeyghjk
    with open('E:/空气质量/pollution.csv','a',encoding='utf-8-sig',newline='') as csvfile:
        write = csv.writer(csvfile)
        #write.writerow(['时间','pm2.5','PM10'])
        write.writerows([
                [a,b,c,d,e,y,g,h,j,k]
                ])

爬虫的时候首先要知道你要点击那些按钮才能找到数据,在网站上按F12可以得到源码,然后在源码左上角可以看到一个类似箭头的东西,点击它再点按钮,可以得到按钮所在的代码,右击copy-copy xpath 可以得到这个按钮的xpath,然后就可以模拟点击。同理获取数据也是要通过xpath找到数据所在的文本框。具体的话可以通过点击代码里面的链接然后看一下源代码。

交通爬虫

交通爬虫和上面差不多,但我获取数据的方式用了另外一种,但是比较坑的是我用表格的xpath还是爬不出数据,最后我发现原来他的网站里面还内嵌了一个网站,最后在那个网站里面爬虫就显示成功。因而爬虫失败的时候要多提醒自己往前看一下源码,说不定就有失败原因的提示。
代码如下:

    driver.get('http://219.136.133.162/gztraffic/Default.aspx')
    driver.refresh()
    time.sleep(30)
    element = driver.find_element_by_xpath('//*[@id="RoadTTI"]')
    element.click()
    time.sleep(5)
    elements = driver.find_elements_by_xpath('//*[@id="RoadTTIList"]')
    for element in elements:
#        print(re.findall('data-bind="text: refreshTime">(.*)</div>',element.get_attribute('innerHTML')))
        list2 = re.findall('data-bind="text: refreshTime">(.*)</div>',element.get_attribute('innerHTML'))
        list = re.findall('data-bind="text: RoadName">(.*)</div>',element.get_attribute('innerHTML'))
        f = open("E:/空气质量/通道名称.txt","a")
        f.write(str(list2))
        f.write("\n")
        for i in range(len(list)):
            for j in range(len(list[i])):
                f.write(str(list[i][j]))
#                f.write("\t")
            f.write(",")
        f.write(",")
        f.close()        
#        print(re.findall('data-bind="text: RoadName">(.*)</div>',element.get_attribute('innerHTML')))
        list = re.findall('data-bind="text: Dir">(.*)</div>',element.get_attribute('innerHTML'))
        f = open("E:/空气质量/方向.txt","a")
        f.write(str(list2))
        f.write("\n")
        for i in range(len(list)):
            for j in range(len(list[i])):
                f.write(str(list[i][j]))
#                f.write("\t")
            f.write(",")
        f.write(",")
        f.close() 
#        print(re.findall('data-bind="text: Dir">(.*)</div>',element.get_attribute('innerHTML')))
        list = re.findall('data-bind="text: RoadTTI">(.*)</div>',element.get_attribute('innerHTML'))
        f = open("E:/空气质量/行程时间比.txt","a")
        f.write(str(list2))
        f.write("\n")
        for i in range(len(list)):
            for j in range(len(list[i])):
                f.write(str(list[i][j]))
#                f.write("\t")
            f.write(",")
        f.write(",")
        f.close() 
#        print(re.findall('data-bind="text: RoadTTI">(.*)</div>',element.get_attribute('innerHTML')))
        list = re.findall('data-bind="text: RoadSpeed">(.*)</div>',element.get_attribute('innerHTML'))
        f = open("E:/空气质量/平均速度.txt","a")
        f.write(str(list2))
        f.write("\n")
        for i in range(len(list)):
            for j in range(len(list[i])):
                f.write(str(list[i][j]))
#                f.write("\t")
            f.write(",")
        #f.write(",")
        f.close() 
#        print(re.findall('data-bind="text: RoadSpeed">(.*)</div>',element.get_attribute('innerHTML')))
        print("done")

我这里的是正则化提取我需要的数据,但后来我发现每个网站爬虫时提取数据的方法可能都有不同,但是我算是外行人,所以我每次爬取新网站我都是逐个方法试。但是有时候用正则化就提取不出来数据emmmm。

另外我还有一个问题就是不知道当网站加载错误的时候应该怎么直接跳出循环,我现在为了避免这个问题在代码里面加了很多refresh,但这个应该不是最好的方法,这种网站最常见的问题是加载的时候按钮的位置会错乱,但论坛里面有说的网站错误并不包含这种,连接时都是成功的,即以下代码并不会报错:

def error_process():
    try:
        import urllib.request
        import urllib.error
        urllib.request.urlopen('http://112.94.64.160:8023/gzaqi_new/RealTimeDate.html')
        print("OK")
    except urllib.error.URLError as e:
        if hasattr(e,"code"):
            print(e.code)
        if hasattr(e,"reason"):
            print(e.reason)

但是程序会提示找不到按钮的xpath了,多刷新几次后网页就会恢复正常,希望有解决这个问题的大佬不吝赐教。

最后我设定是每小时自动爬虫一次,要记得前面类那里最后要加一个diver.quit()
最后是我的主函数:

while(True):
    now=datetime.datetime.now()
    #print(type(now))
    if sched_timer < now < sched_timer+datetime.timedelta(seconds = 1):
        time.sleep(1)
        if __name__ == '__main__':
            error_process()
            main()
        flag = 1
    else:
        if flag==1:
            sched_timer = sched_timer + datetime.timedelta(minutes=60)
            flag = 0

第一次写文章,好麻烦······如果有什么不足之处欢迎评论区多交流,有更好的代码改进方法也请你不吝赐教~

  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值