一、缘起
跟林同学一起学了 python 一周左右的时候,她开始做她的毕业设计,去爬一个网站 。
由于我们都还没接触过动态网站(这里简单的认为是用 ajax 去加载数据的),所以用爬静态网站的方法肯定行不通啦。
然后我查了一小时才发现是数据是动态加载的(真够菜的。。)
二、过程
后来查查资料,发现爬动态网站常用的就几种方法:
1,分析 ajax 请求、参数等,用爬静态网站的方法,直接拿 json 数据。
2,使用 splash 爬取
3,使用 selenium 模拟鼠标操作,去爬取相关数据
第一种方法比较简单,只是分析请求稍微有点费时。林同学用半个小时就用 scrapy 搞定了,才几行代码而已。。
import requests
url = 'http://app.gdstc.gov.cn/sjkf/kjxm'
data = {
'const_dict_id': 10203,
'start': 60,
'length': 30,
}
headers = {'User-Agent': 'Mozilla/5.0(Macintosh;IntelMacOSX10.6;rv:2.0.1)Gecko/20100101Firefox/4.0.1',
"Cookie": "BAIDUID=4650B0B34048BBAA1E0B909B42F5A564:FG=1; BIDUPSID=4650B0B34048BBAA1E0B909B42F5A564; PSTM=1537177909; BDUSS=w0VmEzUFFWTTh0bld5VWVhNVo5MEEyV2ZKdTk3U2stMGZmWVQ1TTRuSnVkOHBiQVFBQUFBJCQAAAAAAAAAAAEAAAD0GzcNaG9uZ3F1YW4xOTkxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG7qoltu6qJbTk; pgv_pvi=6774493184; uc_login_unique=19e6fd48035206a8abe89f98c3fc542a; uc_recom_mark=cmVjb21tYXJrXzYyNDU4NjM%3D; MCITY=-218%3A; cflag=15%3A3; SIGNIN_UC=70a2711cf1d3d9b1a82d2f87d633bd8a02893452711; locale=zh; Hm_lvt_64ecd82404c51e03dc91cb9e8c025574=1539333192; from_lang_often=%5B%7B%22value%22%3A%22en%22%2C%22text%22%3A%22%u82F1%u8BED%22%7D%2C%7B%22value%22%3A%22zh%22%2C%22text%22%3A%22%u4E2D%u6587%22%7D%5D; REALTIME_TRANS_SWITCH=1; FANYI_WORD_SWITCH=1; HISTORY_SWITCH=1; SOUND_SPD_SWITCH=1; SOUND_PREFER_SWITCH=1; to_lang_often=%5B%7B%22value%22%3A%22zh%22%2C%22text%22%3A%22%u4E2D%u6587%22%7D%2C%7B%22value%22%3A%22en%22%2C%22text%22%3A%22%u82F1%u8BED%22%7D%5D; Hm_lpvt_64ecd82404c51e03dc91cb9e8c025574=1539333307",
}
response = requests.get(url, params=data, headers=headers, timeout=10)
print(response.url)
print(response.status_code)
if response.status_code == 200:
content = response.text
print(content)
然而,我用第二种方法,搞了两个小时,还只能拿到第一页的数据,无法拿到翻页的数据。林同学为她拿到数据而开心的时候,我还在很烦躁地 debug。。
后来,我用了第三种方法,终于还是搞定了。代码如下:
import re
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from bs4 import BeautifulSoup
import pymysql
#创建连接
conn = pymysql.connect(
host='localhost', #主机名
port=3306, #端口号(默认的)
user='root', #用户名
passwd='', #密码
db='technology', #数据库名,需要先自己手动新建
charset='utf8', #这里设置编码是为了输出中文
)
#获取cursor
cur = conn.cursor()
browser = webdriver.Chrome()
wait = WebDriverWait(browser, 10)
url = "http://app.gdstc.gov.cn/app/sjkf/kjxm_10203.jsp"
def start():
print('--started--')
try:
browser.get(url)
# 等待 ajax 加载完成
numbers = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "#listTable_paginate > ul > li:nth-child(8) > a")))
get_infos()
return numbers.text
except TimeoutError:
return start()
def next_page(page_number):
print('--paging--')
try:
# 模拟点击下一页
next = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "#listTable_next > a")))
next.click()
# 等待 ajax 刷新完成
wait.until(EC.text_to_be_present_in_element((By.CSS_SELECTOR,"#listTable_paginate > ul > li.paginate_button.active"), str(page_number)))
get_infos()
except TimeoutError:
next_page()
def get_infos():
wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "#listTable_wrapper #listTable")))
html = browser.page_source
soup = BeautifulSoup(html, "html.parser")
trs = soup.select("tr[role='row']")
for tr in trs[1:]:
info = []
for td in tr:
# print(td.text)
info.append(td.text)
save_to_mysql(info)
# 需要自己先手动建一个 infos 的表,关有相关字段
def save_to_mysql(info):
sql = "insert into infos (name, location, firstTime, validTime) values ('%s', '%s', '%s','%s')" % (info[0], info[1], info[2], info[3])
try:
# 执行sql语句
cur.execute(sql)
# 提交到数据库执行r
conn.commit()
except Exception as e:
print('--Save To MYSQL Error--', e)
# Rollback in case there is any error
conn.rollback()
def main():
try:
total = start()
for i in range(2, int(total) + 1):
next_page(i)
except Exception as e:
print('--Error Occurred--', e)
finally:
# 关闭数据库连接
cur.close()
conn.close()
browser.close()
print('--ended--')
if __name__ == '__main__':
main()
三、后记
写这篇文章主要是为了记录一下我枯燥的学习过程。
四月份前两周主要在学机器学习,那时候觉得,要学的知识又多又难,我学习效率又低,智商也低,真的压力好大。可惜只坚持了两周就不行了。感觉比考研前一个月还累。晒一下前两周的学习时间表:
然后这几天主要在学 python 爬虫。
入门 python 爬虫比入门机器学习简单一百倍。。于是现在经常睡到自然醒,无聊了就看电影,做条咸鱼,真是太舒服了。。