本篇文章是用requests請求烙样,beautifulsoup進行解析冯遂;如果是找正則表達式、urllib案例的同學建議學習其它資料谒获。
ps:如果是找案例的同學可直接看最后代碼部分蛤肌,如果你和我一樣入門爬蟲從文章開頭閱讀羅。
前言:自學爬蟲第15天批狱,終于成功爬取58同城月嫂招聘信息并保存至mysql數(shù)據(jù)庫……寫下這篇文章分享給自學爬蟲的你裸准。數(shù)據(jù)不完善之處:由于某些網(wǎng)頁會把某些信息隱藏,導致爬取的pos_base_browser, pos_base_apply數(shù)據(jù)為空赔硫,這個問題還在解決中炒俱。
感悟:自己在學習期間心態(tài)也不穩(wěn)定,會有臨陣脫逃的沖動爪膊,而讓自己堅持下來動力是不斷解決一個又一個的問題权悟、知識體系的不斷升級。15天重復著找資料推盛、百度峦阁、百度翻譯的過程;最害怕看見代碼報錯耘成;最經(jīng)忱莆簦看見的一個錯誤是**out of range驹闰。雖沒人帶花費了很多時間找資料,但在不斷的探索中也收獲了一解決問題的思路:少問人多思考—翻譯—百度撒会。
文章分為四個部分:
一嘹朗、我的爬蟲學習目標
二、爬蟲學習升級過程:入門10點
三诵肛、學習過程中的坑
四屹培、58同城月嫂招聘信息代碼
五、我待解決問題
一曾掂、我的爬蟲學習目標
1惫谤、了解html、css珠洗、javascrpt
2溜歪、掌握requests、beautifulsoup庫
3许蓖、會模仿爬蟲案例
二蝴猪、爬蟲學習升級過程:入門10點
1、了解html膊爪、css自阱、標簽
2、學習requests米酬、beautifulsoup庫沛豌;會get請求、會通過標簽選擇相應的文本赃额,會通過標簽選擇屬性
3加派、理解靜態(tài)加載(翻頁請求)、動態(tài)加載(Ajax)
4跳芳、理解函數(shù)循環(huán)
5芍锦、理解def main() :函數(shù)、name = "main()":函數(shù)
6飞盆、理解print和return的區(qū)別
7娄琉、理解索引頁(列表頁)、詳情頁吓歇,索引頁在解析詳情頁url時返回的字典(用于循環(huán))
8孽水、會數(shù)據(jù)庫的存儲,需要在mysql數(shù)據(jù)庫中創(chuàng)建數(shù)據(jù)庫和字段類型城看,詳情看第二部分代碼女气。
9、建議使用pycharm
10析命、半自主解決學習過程中出現(xiàn)的任何問題
三主卫、學習過程中的坑:
知道自己會遇見什么問題、問題的類型鹃愤,在學習中即使出現(xiàn)問題通過百度也可解決簇搅。
自己在學習中因為不知道如何提問(因為不了解連提問都不會)走了很多彎路。
eg1:在解析索引頁時不知道結果應該返回字典的格式软吐,然后折騰整整2天才恍然大悟瘩将,字典可以遍歷,將url保存為字典可以請求詳情頁凹耙。
eg2:群主一直建議我把爬取下來的文件保存到數(shù)據(jù)庫姿现,我也看了相關的視頻。在不斷刪除肖抱、定義pymysql函數(shù)中勇敢嘗試去解決錯誤备典,終于知道在mysql中新建數(shù)據(jù)庫新建表新建表中字段。
當自己不會的時候就去模仿意述,當模仿過程中出現(xiàn)問題時就去百度提佣。
eg3:沒找到requests請求,beautifulsoup解析靜態(tài)加載的案例荤崇。拼拼湊湊很多視頻拌屏、代碼
……回想起來中間很多迷茫,但這是畢竟之路术荤,只有親身體會才能收獲成長倚喂。希望這篇文章能給轉數(shù)據(jù)分析學爬蟲的你一點點幫助。
四瓣戚、58同城月嫂招聘信息代碼
1端圈、目標網(wǎng)點:
https://cd.58.com/yuesaoyuying/?key=月嫂
2、爬取信息:
索引頁公司名稱带兜;詳情頁招聘標題枫笛、更新時間、瀏覽人數(shù)刚照、申請人數(shù)刑巧、工資
(PS:其實我還想知道索引頁的推廣方式、發(fā)布地址无畔。學了15天還不知道怎么同時保存索引頁和詳情頁的多個內容)
3啊楚、爬蟲代碼
《pycharm代碼》
import json
import pymysql
import requests
from bs4 import BeautifulSoup
from requests.exceptions import RequestException
headers = {
'user-agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36"}
def get_one_page(url):
try:
respones = requests.get(url, headers=headers)
respones.encoding = 'utf-8'
if respones.status_code == 200:
return respones.text
return None
except RequestException:
print('請求錯誤')
return None
def parse_one_page(html):
soup = BeautifulSoup(html, 'lxml')
soup = BeautifulSoup(html, 'lxml')
list_li = soup.find_all('ul', id='list_con')[0].find_all('li', class_='job_item clearfix') # 返回一個列表需要用循環(huán)
dir = {}
for link in list_li:
list_a = link.find_all('div', class_='job_name clearfix')[0].find_all('a')[0] # 篩選出所有的a標簽
address = list_a.find_all('span', class_='address')[0].text
name = list_a.find_all('span', class_='name')[0].text
comp_name = link.find_all('div', class_='comp_name')[0].find_all('a')[0].text
href = list_a['href']
t = list_a['_t']
dir[href] = comp_name
return dir
def get_two_page(url):
try:
respones = requests.get(url, 'lxml')
if respones.status_code == 200:
return respones.text
return None
except RequestException:
print('請求詳情頁錯誤')
return None
def parse_two_page(html,comp_name):
comp_name = comp_name
soup = BeautifulSoup(html, 'lxml')
#pos_base = soup.find_all('div',class_ = 'pos_base_statistics')[0]
pos_name = soup.find_all('span',class_ = 'pos_name')[0].text
pos_base_update = soup.find_all('span', class_='pos_base_num pos_base_update')[0].find_all('span')[0].text # 更新日期
pos_base_browser = soup.find_all('span', class_='pos_base_num pos_base_browser')[0].find_all('i', id='totalcount')[0].text # 瀏覽量
pos_base_apply = soup.find_all('span', class_='pos_base_num pos_base_apply')[0].find_all('span', id='apply_num')[0].text # 申請數(shù)
pos_salary = soup.find_all('div', class_='pos_base_info')[0].find_all('span', class_='pos_salary')[0].text # 工資水平
return comp_name,pos_name, pos_base_update,pos_base_browser, pos_base_apply, pos_salary
def save_to_mysql(comp_name,pos_name, pos_base_update,pos_base_browser, pos_base_apply, pos_salary):
cur = conn.cursor() #用來獲得python執(zhí)行Mysql命令的方法,操作游標浑彰。cur = conn.sursor才是真的執(zhí)行
insert_data = "INSERT INTO 58yuesao(comp_name,pos_name, pos_base_update,pos_base_browser, pos_base_apply, pos_salary)" "VALUES(%s,%s,%s,%s,%s,%s)"
val = (comp_name,pos_name, pos_base_update,pos_base_browser, pos_base_apply, pos_salary)
cur.execute(insert_data, val)
conn.commit()
conn=pymysql.connect(host="localhost",user="root", password='18030823940',db='58yuesao',port=3306, charset="utf8")
def main():
urls = ['https://cd.58.com/yuesaoyuying/pn{}/?'.format(i) for i in range(1, 8)]
for url in urls:
html = get_one_page(url)
dir = parse_one_page(html)
for href, comp_name in dir.items():
html = get_two_page(href)
comp_name, pos_name, pos_base_update, pos_base_browser, pos_base_apply, pos_salary = parse_two_page(html,comp_name)
save_to_mysql(comp_name, pos_name, pos_base_update, pos_base_browser, pos_base_apply, pos_salary)
if __name__ == '__main__':
main()
《pycharm關聯(lián)mysql代碼》
create database 58yuesao;
use 58yuesao;
create table 58yuesao
(comp_name varchar(40) not null,
pos_name varchar(20) not null,
pos_base_update varchar(15) not null,
pos_base_browser int not null,
pos_base_apply int not null,
pos_salary varchar(20)not null);
ALTER TABLE 58yuesao CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci
最后在數(shù)據(jù)庫里面就可以看見自己爬取的文件了恭理,用count()可以看見一共爬取了239條數(shù)據(jù)
五、我待解決問題
1郭变、同時爬取索引頁和詳情頁多個內容
2颜价、Ajax異步加載
3涯保、抓取背網(wǎng)頁屏蔽掉的信息(如: pos_base_browser, pos_base_apply)
明天繼續(xù)解決問題,加油周伦!