首先倒入模块,threading多线程可以大幅提升速度,不过记得限制并发数量。
import requests import re import threading import random import csv
请求头设置这里不赘述,可在前面文章找到。
通过分析得知,我们需要请求列表页及列表页中各个详情页的车辆信息。
因为首页的url不符合其余页面的规律,所以单独提出来定义一个get first page
def get_first_page():
url = 'https://so.iautos.cn/quanguo/baoma/'
response = requests.get(url=url, headers=headers,verify=False, timeout=5)
html = response.text
parse_page(html)
def get_detail_page(pagenum):
url = f'https://so.iautos.cn/quanguo/baoma-p{pagenum}asdsvepcatcpbnscac/'
response = requests.get(url=url,headers=headers,verify=False, timeout=5)
html = response.text
parse_page(html)
semaphore.release()
拿到所有列表页的url后,接下来定义解析详情页信息的函数。这里使用了正则表达式,当然七大解析库比如bs、lxml、pyquery也是可以的。
注意:因为findall返回的是一个列表,所以用zip来把每辆车对应的name、img等信息整合到一个列表中。
def parse_page(html):
name_pattern = re.compile('s+s* (.*?)')
mile_pattern = re.compile('(.*?)公里 ')
price_pattern = re.compile('¥(.*?)')
#findall返回一整个列表,所以要zip一下,让每个列表的第xx个数据匹配一起
name = name_pattern.findall(html)
img = img_pattern.findall(html)
regdate = regdate_pattern.findall(html)
mile = mile_pattern.findall(html)
price = price_pattern.findall(html)
l = zip(name, img, regdate,mile,price)
save_car(l)
最后定义save函数,并打开一个csv文档,保存数据。
主函数中,利用boundedsemaphore限制信息量,也就是限制线程并发数量,毕竟目的是学习 。
def save_car(l):
for index, value in enumerate(l):
#writerow只能返回一个参数,所以这里用中括号全都扩起来成一个列表
csv_writer.writerow([value[0],value[1],value[2],value[3],value[4]])
f = open('baoma_more.csv','w', encoding='utf-8')
csv_writer = csv.writer(f)
csv_writer.writerow(['Name','img','register date','Kilometers','Price'])
if __name__ == '__main__':
get_first_page()
semaphore = threading.BoundedSemaphore(5)
lst_rec_threads = []
for i in range(2,50):
semaphore.acquire()
t = threading.Thread(target=get_detail_page, args=(i,))
t.start()
lst_rec_threads.append(t)
for rt in lst_rec_threads:
rt.join()
f.close()
成果展示



